2014-06-28 39 views
0

我以爲我知道JavaScript,似乎我不知道。使用`this`與對象文字

我想定義一個像這樣的對象。 (從http://www.phpied.com/3-ways-to-define-a-javascript-class/例)

var apple = { 
    type: "macintosh", 
    color: "red", 
    getInfo: function() { 
     return this.color + ' ' + this.type + ' apple'; 
    } 
} 

嗯,這看起來不錯,讓我們打印信息...

apple.getInfo() //returns "red macintosh apple" as expected 

OK,現在就功能並再次運行...

var func = apple.getInfo; func(); //returns "undefined undefined apple" 

那麼,那不是我所期望的。顯然,this被解釋爲window。這不是我想要的。

我的問題是 - 什麼是重寫apple文字的慣用,首選方法,以便apple.getInfo返回一個函數,可以單獨運行,但仍然使用對象屬性?

+0

另請參閱http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback –

回答

6

this的工作方式是,它取決於它如何被調用。知道this的一個快速提示是查看調用中函數名稱前面的對象。

apple.getInfo()使得this參考apple。但將其稱爲func()就好像調用window.func()(假設它在全局空間中),這使得this參考window

如果要在功能上「強制」this的值,請執行bind。它會在第一個參數通過時創建一個與this強制關聯的函數副本。

var func = apple.getInfo.bind(apple); 
// all calls to `func` will have `this` "forced" as `apple` 

如果要規定對呼叫thisfunc不會永久篡改this(如bind怎麼做的),你可以用callapply去:

var func = apple.getInfo; 
func.call(apple); 
func.apply(apple); 
// Both function will have `this` as `apple` only for the call. 
+0

嗯,有趣!我不知道這是複雜的。我需要一個函數來調用回調函數,我想我可以使用'apple.getInfo'而不是創建匿名函數。好的,那麼我會再創建一個匿名函數。謝謝! –

+0

附錄:我實際上最終使用.bind而不是匿名函數,因爲它只是「看起來」更乾淨。 (不知道它是否更快/更高效,或者沒有。) –

+0

呃,我錯了!在所有瀏覽器上,閉包*確實比綁定更高效。 http://jsperf.com/bind-vs-self-closure/7 –

1

@Joseph夢想家已經提出了一個很好的答案。

由於OP正在尋找一種方法來讓apple.getInfo總是返回一個沒有undefined問題的函數,我想我會拋出這個選擇。

var apple = { 
    type: "macintosh", 
    color: "red" 
}; 

apple.getInfo = (function() { 
    return this.color + ' ' + this.type + ' apple'; 
}).bind(apple); 

這樣,您就沒有你想要創建一個新的參考函數每次調用apple.getInfo.bind(apple)

請注意,您不能將getInfo放在原始對象字面值內,因爲此時apple沒有分配值,.bind(apple)將無法​​正常工作。