极客,
我有以下代码:
代码段A:
var x = (function(){ this.id="Dog"; return this; }());
var y = (function(){ this.id="Cat"; return this; }());
alert(x.id); //outputs Cat
alert(y.id); //outputs Cat
摘录B:
var x = (new function(){ this.id="Dog"; });
var y = (new function(){ this.id="Cat"; });
alert(x.id); //ouputs Dog
alert(y.id); //outputs Cat
为什么x在代码片段A中被y替换而不在B上?
答案 0 :(得分:3)
两者之间的区别在于,代码段B使用 constructor function 作为前缀,使用new
关键字作为前缀,而不是代码段A.这是简短的答案。
答案很长,虽然代码片段A在每个匿名函数调用中引入了一个新范围,但由于不在构造函数上下文中使用,因此它的this
变量只指向全局window
对象。所以代码片段A相当于:
var x = (function(){ window.id="Dog"; return window; }());
var y = (function(){ window.id="Cat"; return window; }());
因此,每次调用只会破坏相同的[全局]变量。
由于代码段B使用new
关键字,因此您可以定义并立即调用构造函数。 JavaScript继续初始化构造函数内的this
变量,指向[刚定义的]匿名函数的新实例。
前段时间你可能已经看到new function(){}
成语被吹捧为定义和立即执行代码块的最佳方式。好吧,它带来了JavaScript对象实例化的开销(正如你所发现的那样),并且通常不再广泛使用。
答案 1 :(得分:2)
在代码段A中,在x和y上,this
关键字引用全局对象,您正在创建将值设置为相同的全局变量(window.id
)。
在代码段B中,您使用new
运算符,函数作为构造函数执行,this
关键字引用新创建的对象。
为了避免代码段A中的这种行为,您可以创建一个新的对象实例并使用它代替this
:
var x = (function(){
var instance = {};
instance.id = "Dog";
return instance;
}());
var y = (function(){
var instance = {};
instance.id = "Cat";
return instance;
}());
alert(x.id); //outputs Dog
alert(y.id); //outputs Cat
调用全局函数时,因为它们是全局对象的成员:
globalFunction();
相当于:
window.globalFunction();
该函数内的上下文将是全局对象本身(window
)。