2009-12-09 54 views
0

極客,javascript對象在IE被重寫

我有以下代碼:

列表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

在片斷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(); 

一nd該函數內的上下文將是全局對象本身(window)。

+0

+1好答案 –

3

這兩者之間的區別是,片段B被使用constructor function由前綴與關鍵字new呼叫,而片斷A不是。這是簡短的答案。

長的答覆是,雖然片段一介紹了每個匿名函數調用一個新的範圍,因爲它是在它this變量簡單地指向全球window對象的構造背景下被使用。因此,片段A等同於:

var x = (function(){ window.id="Dog"; return window; }()); 
var y = (function(){ window.id="Cat"; return window; }()); 

因此,每個調用只會覆蓋同一個[global]變量。

由於片段B正在使用關鍵字new,因此您可以定義並立即調用構造函數。 JavaScript繼續初始化構造函數中的this變量,以指向[剛剛定義的]匿名函數的新實例。

前段時間,您可能已經看到new function(){}成語被認爲是定義和立即執行代碼塊的最佳方式。那麼,它帶來了JavaScript對象實例化的開銷(正如你找到的那樣),並且通常不再被廣泛使用。