2010-05-06 61 views
1

在Javascript中,如果我們混疊的功能(或者,分配一個「參考到功能」到另一變量),如在:在Javascript中,只要被別名的函數不觸及「this」,函數別名是否正常工作?

f = g; 
f = obj.display; 
obj.f = foo; 

3個上面的行的所有的,只要它們將工作右側的功能/方法不會觸及this?既然我們傳遞了所有的參數,那麼它可能會搞砸的唯一方式是右邊的函數/方法使用this

其實第1行可能是好的,如果g也是window的屬性?如果g引用obj.display,那麼同樣的問題在那裏。

在第2行中,當觸摸obj.displaythis,它是指obj,但是當被調用f,將thiswindow,所以它們是不同的。

在第3行,它是相同的:當fobj的代碼中調用,則thisobj,而foo可能使用thiswindow如果是的window的性質。 (全局功能)。

那麼第2行可以寫成

f = function() { obj.display.apply(obj, arguments) } 

和線路3:

obj.f = function() { foo.apply(window, arguments) } 

這是正確的方法?除此之外還有其他方法嗎?

+0

這使我想到M.C.的錘子 – hobodave 2010-05-06 06:17:28

+0

我知道。我試圖在原始問題中不提及這一點。 – 2010-05-06 06:19:23

+0

恭喜,您剛剛發現我討厭Javascript中面向對象編程的原因。 由於缺少綁定函數,您總是需要關注上下文以及(因此)指出的內容。現在你可以繼續使用真正的OOP語言了(對不起:)。 – wump 2010-05-06 06:24:58

回答

3

但是,基本上可以,在JavaScript中,函數是第一類對象,所以它並不是真正的別名。你正在做的是將變量的值賦給另一個變量,在這種情況下,該值恰好是一個函數。

魔法這個變量然而是有點不同。在JavaScript中,方法不會綁定到類或對象,就像它們在大多數其他語言中一樣。當您調用某個方法時,這個由點運算符設置,或者由應用調用方法設置。它的工作原理是這樣的:

var i = 1; 
var f = function() { alert(this.i); } 
f(); // in a browser, alerts 1, because this will be window if it isn't anything else. 

var obj = { i: 10 }; 
obj.g = f; 
obj.g(); // alerts 10, because the dot binds this to obj 

var other_obj = { i: 23 }; 
f.apply(g); // alerts 23, because now apply binds this to other_obj 

您可以通過使用綁定封方法對象:

var f = function() { alert(this.i); } 
var obj = { i: 10 }; 

obj.m = function() { f.apply(obj); } 
obj.m(); // alerts 10 

var g = obj.m; 
g(); // alerts 10, because now the closure is called, which binds this correctly. 
1

「this」和範圍適用於函數(特別是回調函數)的含義似乎是一個經典的JavaScript「gotcha」。

Dojo有一個解決問題的hitch()方法,給出了一個很好的方法來獲得回調方法的預期上下文。我想一個非dojo開發人員可以看看Dojo hitch()代碼來借鑑這些想法。

這個article解釋了「這個」問題的一些方面以及如何使用Dojo hitch()。

1

「這」只會是指正確的對象你的函數裏面,如果你用這種方式調用對象:

obj.f(); 

這不會有任何效果,如JavaScript缺少對「綁定功能」支持(沒有按」不記得什麼對象的方法屬於):

var x = context.lineTo; 
x(10,10); 

了lineTo會感到困惑,「本次」現在指向,而不是其預期的背景下,窗口或電流的函數對象。所以確實,你總是需要適用於你的情況。