2011-07-02 35 views
5

此代碼導致在控制檯上記錄"!"JavaScript和匿名函數中閉包的細節

var g = {}; 
(function() { 
    var t = this; 
    t.x = "x"; 
    g.a = function() { 
     console.log(t.x); 
    }; 
})(); 

(function() { 
    var t = this; 
    t.x = "!"; 
    g.b = function() { 
     console.log(t.x); 
    }; 
})(); 

g.a(); 

匿名函數共享一個this嗎?我使用this錯了嗎?我真的不明白這裏發生了什麼。

我想讓g.a()繼續返回第一個匿名函數中定義的x的值。

我正在使用node.js,如果它有所作爲。

回答

4

在即時函數中,this指的是global object[docs]。因此,在這種情況下,這兩種功能this確實是指相同的元素,你是用第二個呼叫覆蓋x

什麼對象this是指由函數如何調用確定。

  • 如果你只是執行與funcName();功能,然後this全局對象
  • 如果功能被分配到一個對象,obj.funcName()的屬性,this指對象。
  • 如果用new運算符調用該函數,則new funcName();,this引用從函數原型繼承的空對象。

您還可以顯式地使用call[docs]apply[docs]設置this


而是指this,您可以創建兩個功能一個新的對象:

var t = {}; 

附加說明:沒有什麼差別,你無論是在瀏覽器中運行的代碼或與node.js.全局對象是規範的一部分,必須由執行環境提供。在瀏覽器中它是window對象,我不知道它是什麼在node.js中,但只要它遵循說明書中所沒有。

+0

有時候'this'不是指這個函數嗎? –

+3

@luxun:你的意思是功能本身?沒有永不。 –

+3

好吧,除非你專門設置了一些東西,否則它就會有點奇怪。它肯定不會默認或任何東西。 – Pointy

3

費利克斯·克林是正確的長的答案。但我想用我認爲你真的想幫腔:

var g = {}; 
(function() { 
    var x = "x"; 
    g.a = function() { 
     console.log(x); 
    }; 
})(); 

(function() { 
    var x = "!"; 
    g.b = function() { 
     console.log(x); 
    }; 
})(); 

g.a(); // "x" 
g.b(); // "!" 

現在g.a()g.b()都打印出來x,但每個功能與關閉共享自己單獨x。如果這些變量應該是私人的,只能在這些函數的內部進行訪問,這就是你如何隱藏它們,並通過多次調用來堅持它們。

1

當我在Chrome的調試器中查看這個腳本時,就會發現它的匿名函數中的「this」值被設置爲全局變量「window」。這意味着每個匿名函數都將值設置爲window.x,因此最後執行的一個成功並且是可以繼續存在的值,因此在執行第二個匿名函數後執行window.x == "!"

目前還不清楚你期望「這個」是什麼,或者你實際上試圖用這個代碼來完成什麼,所以我不知道有什麼替代方案。如果你只是想讓匿名函數中的前一個狀態在內部函數中生存下來,那麼你可以只依賴局部變量(它將在閉包中存活),而不是使用「this」引用。 Squeegy的例子顯示。