首先,让我们先来看一道关于this的面试题:
function foo(arg){
this.a = arg;
return this
}
var a = foo(1);
var b = foo(10);
console.log(a.a);
console.log(b.a);
以上这段代码在浏览器的环境下的运行结果是undefined 10,而在node环境中的运行结果是10 10。这是为什么呢?
我们首先分析这段代码浏览器的运行:首先将foo(1)执行,执行结果赋给了a;然后再将foo(10)执行,执行结果赋给b。首先在foo(1)执行过程中,this.a = arg;中的this指向window,并且给window添加了一个变量a = 1;然后将window重新赋值给a;此时a为window(造成了循环引用);接下来执行foo(10),在执行this.a = arg时,将window上的全局变量a的值重新置为了10,然后将这个window重新赋值给b;在这个过程中a值经历了1 -> window ->10的变化,这样最终的结果就是a = 10 ,b = window。自然a.a 为undefind,b.a = 10;
在node的环境下,执行foo(1)时,由于是非严格模式,this指向全局对象global,this.a = arg时,给global显示的增添了一个a的属性1,然后将global对象返回给a;执行foo(10)时,重新将a赋值为10。然后将global又赋值给b,最终的结果a === b === global,global.a的值为10;
因此,从这道题中我们可以得出这样一个结论:在浏览器环境下用var声明的变量自动挂载到全局对象window上,而node环境中则必须在函数内部以显示的this.a = a的声明方式才能将变量挂载至全局对象global上。