2013-04-12 50 views
0

我期待從getName2和getName3相同的行爲,但getName3(在非嚴格模式打印「的窗口」)時會引發錯誤不同行爲

"use strict"; 

var name = 'The Window'; 
var object = { 
    name : 'The Object', 
    getName: function(){ 
     alert(this.name); 
    } 
}; 

object.getName(); // The Object 

object.getName2 = object.getName; 
object.getName2(); // The Object 

(object.getName3 = object.getName)(); // Error: TypeError: this is undefined 

該代碼是從例如衍生在N.Zakas的專業JavaScript for Web Developers的第7章中。

回答

2

函數的上下文取決於它如何被稱爲。在你的最後一個例子中,你使用了一個grouping operator(一對圓括號),它返回對object.getName所提及的函數的引用。它失去了object的背景。

當你再調用這個函數,因爲它失去了object的背景和你在嚴格模式下運行,上下文成爲全球對象和thisundefined。您可以強制功能在object通過上下文中運行,例如,明確將其綁定到它:

(object.getName3 = object.getName).bind(object)(); // The Object 
+0

感謝@詹姆斯阿勒代斯,但爲什麼括號內不會對getName2同樣的效果? '(object.getName2)(); // The Object' –

+0

因爲'(o.g3 = o.g)'返回* assignment *的結果,這是一個函數(沒有上下文)。 '(o.g2)'返回帶有上下文的函數。考慮這個:var x = object.getName; X();'。這就是發生的事情。 –

+0

好了,現在我明白了,這是分配和執行的組合,它們會產生不同的行爲。 賦值只傳遞一個沒有附加上下文的函數,上下文由對象提供。 最後,getName2和getName3之間沒有區別。 '// non-strict mode' '(object.getName3 = object.getName)(); // The Window' '(object.getName3)(); // The Object' 謝謝! –