2013-10-02 123 views
2

有繼承最流行的JavaScript方法:的JavaScript通過繼承原型

function extend(Child, Parent) { 
    var F = function() { } 
    F.prototype = Parent.prototype; 
    Child.prototype = new F(); 
    Child.prototype.constructor = Child; 
    Child.superclass = Parent.prototype; 
} 

我學JS了,但我有很多的Java經驗,這種繼承模式似乎有些diffucult我。爲什麼我不能做以下事情:我認爲我不知道/理解一些事情,但F對象在我看來是無用的。請澄清情況。謝謝。

+1

在你的第二個例子,'Child.prototype === Parent.prototype'這將意味着到'Child.prototype'任何改變也會改變'Parent.prototype',因爲他們會在同一個參照同目的。 – zzzzBov

+0

最好避免試圖從Java繼承的角度考慮JavaScript繼承。這兩種架構**非常**不同。 – Pointy

+0

對於現代瀏覽器,您可以使用Object.create來設置繼承。我試圖在這個答案中描述原型,繼承,覆蓋和調用超級:http://stackoverflow.com/a/16063711/1641941瞭解「this」引用的內容也許很有用:http:// stackoverflow.com/a/19068438/1641941 – HMR

回答

5
Child.prototype = Parent.prototype; 

現在Child.prototypeParent.prototype同一個對象

將方法添加到Child.prototype將把它們添加到Parent.prototype,這是而不是 OOP繼承是如何工作的。

0

我相信,一個javascript prototype是對象的實際情況,如果你這樣做:

Child.prototype = Parent.prototype; 
Child.prototype.constructor = Child; 

你也可以改變Parent的原型也是如此,因爲他們是同一個對象的實例。

2

實現最重要的事情是,JavaScript沒有內置的原生類繼承。它不像Java,所以如果你想使用JavaScript的原型,你會想把所有的Java繼承想法都放在窗口外面。

原型的想法是,你必須連接到構造函數的單個對象。這是你的原型對象。您可以使用構造函數來生成新的對象,這些對象都可以訪問構造函數原型中包含的方法。訣竅是,如果您修改了附加到構造函數的原型,那麼您更改的方法現在將針對構造函數創建的所有子對象進行更改。它的工作原理是這樣的:

function Cat(name) { 
    this.name = name; 
} 

Cat.prototype = { 
    furColor: function() { 
    return 'gray'; 
    } 
}; 

var kitty1 = new Cat('Bob'); 
//=> {name: 'Bob'} 

kitty1.furColor(); 
//=> 'gray' 

Cat.prototype.furColor = function() { 
    return 'white'; 
} 

var kitty2 = new Cat('Sally'); 
//=> {name: 'Sally'} 

kitty2.furColor(); 
//=> 'white' 

kitty1.furColor(); 
//=> 'white' 

所以,如果你想建立經典的繼承過這種模式,你可以的,但是要記住,這是你在JavaScript中的原型得到什麼。

有一個非常流行的經典的繼承的插件,讓你一些不錯的OO的JavaScript稱爲klass你可能想嘗試滾動自己的來代替。

+0

謝謝。請另外說一些 - 我知道通過原型添加類的方法,但是可以在「構造函數」函數中添加類的方法嗎?什麼方式更好? – malcoauri

+1

添加原型。從馬的嘴裏說道:「我現在看到我早期嘗試用JavaScript支持經典模型是一個錯誤。」 http://www.crockford.com/javascript/inheritance.html我完全同意。爲什麼假如它不在那裏呢?如果你想學習日語,你會學習日語,你不會去設想自己的日語方言,並希望日本人會學習它以理解你。 – itmitica

+0

但是,您可以將函數分配給構造函數中的對象,該函數將被視爲該對象的「擁有屬性」。當它在原型中時,它不被視爲生成對象的實際成員屬性。優點和缺點。這完全取決於你想要完成的事情。但是,就像你不應該嘗試用Haskell風格編寫Java一樣,你可能不想真正用Java風格編寫JS。 – rescuecreative