2011-10-18 45 views
0

我有一個fiddle幫助我理解JavaScript原型和繼承。評論講述了這個故事。瞭解原型和增強

//From Douglas Crockford's "Javascript: the good parts": a helper to hide the "ugliness" of setting up a prototype 
Function.prototype.method = function(name,func) { 
    this.prototype[name] = func; 
    return this; 
} 

function SomeFunc(value) { 
    this.setValue(value); 
} 

//Inherit the function (to me this conceptually the same as adding a member to a class) 
SomeFunc.method('setValue', function (value) { 
    this.value = value; 
    return this; 
}); 

try 
{ 
SomeFunc(1); 
} 
catch(e) 
{ 
    alert(e); 
} 

爲什麼我會得到異常?我的筆記是否正確,因爲JavaScript調用繼承是古典程序員簡單地向類中添加新成員?增強和繼承有什麼區別?

+0

一開始的情況下,看看[使用對象](https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects)和[繼承和原型鏈](https://developer.mozilla.org/zh/JavaScript/Guide/Inheritance_constructor_prototype)。 –

+1

你在'SomeFunc(1)'之前忘了''''' – Kru

+0

@Kru - 修正了錯誤。爲什麼需要新的? –

回答

6

我的筆記正確的是JavaScript調用繼承是古典程序員簡單地向類添加一個新成員?

不,不是真的。在JavaScript中,我們有基於原型的繼承。這意味着一個對象可以引用另一個對象,即其原型。無論何時訪問對象的屬性,都會搜索原型鏈以查找此屬性。因此,如果該對象本身沒有該屬性,則會檢查其原型是否屬於該屬性等等。

+------------+ +-------------+ 
| Instance | | Prototype | 
| __proto__ -+--->| __proto__ -+-->... 
| foo  | | bar  | 
+------------+ +-------------+ 

Instance兼備,所述foobar性質。

現在,如果你有一個構造函數,你可以創建很多引用同一個原型的實例(對象)。當您現在向該原型添加新屬性時,所有實例也會擁有該屬性(由於原型鏈)。

這通常是爲了動態擴展實例而完成的,但這只是原型繼承的一個結果,它不是繼承本身。

增強和繼承有什麼區別?

繼承可以將對象的原型設置爲某個對象,以使其位於原型鏈中。擴充只是複製屬性。對象將自己該屬性則:

+------------+ 
| Instance | 
| __proto__ -+--->... 
| foo  |  
| bar  | 
+------------+ 

爲什麼我得到一個異常?

因爲你打電話SomeFunc就像一個「正常」的功能,而不是像一個構造函數。在這種情況下,this將參考window,它沒有setValue方法。

而是要與new operator [MDN]稱呼它,創建一個新的實例:

var instance = new SomeFunc(1); 

如果這樣調用,this將把它從構造函數的prototype財產繼承一個空對象(SomeFunc.prototype) 。

MDN has a nice article about this and what it refers to in certain situations.

如果你看一下method是幹什麼的,你看,它增加了一個新的屬性SomeFunc.prototypethisSomeFunc):

this.prototype[name] = func; 

事實上,是第一部分你的代碼正在做的是我上面提到的:通過擴展Function.prototype,你可以爲每個函數添加一個新的屬性,這讓你稍後可以調用SomeFunc.methods


延伸閱讀:

+0

你忘了'新'。 ;)+1雖然。 – user113716

+1

謝謝...... D –

+1

......啊,我看到你正忙着製作你喜歡的圖形插圖。 :) – user113716

0

嘗試,而不是:

new SomeFunc(1); 

,因爲這是當工程樣機