javascript对象在IE中被覆盖

时间:2009-12-09 03:51:29

标签: javascript

极客,

我有以下代码:

代码段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上?

2 个答案:

答案 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)。