2013-08-23 49 views
0

任何人都可以解釋JavaScript通過調用方法來選擇哪個函數運行的過程?我可以找到的大多數在線資源都解釋瞭如何使用JavaScript對象實現特定行爲,但不解釋方法派發在JavaScript中如何工作的一般原則。JavaScript方法調度過程

回答

3

「Method dispatch」實際上只是屬性查找,因爲JavaScript中的「methods」只是通過對象屬性使用的函數。 (更多關於我的博客:Mythical methods

當你寫:

obj.prop 

JavaScript引擎着眼於obj對象,看它是否有一個名爲"prop"的屬性。如果是,則使用該屬性的值。如果不是,則引擎會查看obj的原型對象,看看是否具有該名稱的屬性。如果是這樣,它使用它的值。如果不是,則看對象的原型。沖洗,重複,直到它用完原型對象。

沒有任何種類的「方法簽名」匹配,如在某些允許方法重載的語言中。 JavaScript沒有方法重載。只能有一個附加到具有給定名稱的對象的標籤。

讓我們來看一個例子:

function Thing() { 
} 
Thing.prototype.test = function() { 
    return "Thing#test"; 
}; 

var t = new Thing(); 
t.own = function() { 
    return "My own"; 
}; 

現在讓我們用t玩:

console.log(t.own()); // Logs "My own" 

爲了表達t.own,發動機看着t,看它是否有一個名爲"own"屬性。它的確如此,所以使用該屬性(函數)的值。 ()之後它調用函數,它返回"My own",我們就完成了。

console.log(t.test()); // Logs "Thing#test" 

爲了表達t.test,發動機着眼於t,看它是否有一個名爲"test"屬性。它沒有,所以引擎看着t的原型。 t的原型是Thing.prototype,在表達式new Thing期間被分配給它。 Thing.prototype有一個"test"屬性,所以使用該值(一個函數)。然後在調用該函數後返回(),該函數返回字符串"Thing#test"

console.log(t.toString()); // Logs "[object Object]" 

發動機着眼於t,沒有找到"toString"屬性,所以它看起來在t的原型,並沒有找到"toString"屬性,所以它看起來在t的原型的原型(其中是Object.prototype)。那確實有一個"toString"屬性,它的值是一個函數。然後()調用該函數,該函數返回"[object Object]"

最後,爲了完整性:

console.log(t.foo());  // Throws an error 

,發動機不會找到t"foo"t的原型,或t的原型的原型。現在它沒有原型,因此表達式t.foo的結果爲undefined。然後我們嘗試通過()調用它,這是我們無法做到的,因爲undefined不是函數。