1

我想知道,鑑於JavaScript的原型繼承的限制,是否有可能仿效其他OOP語言中所見的基於類的繼承。Javascript - 可以模擬經典的OOP繼承嗎?

我創建了一個超類和子類,如下所示:

//Parent 
function Animal(i) 
{ 
    //Some constructor implementation 
} 

//Child 
function Pig(i) 
{ 
    //Some additional constructor implementation 
} 

Pig.prototype = new Animal(); 

我可以保證的是,孩子這樣,我並不需要顯式調用,或者創建他們的方式繼承其父的功能孩子的對象?

Animal.prototype.eat = function() 
{ 
    console.log("eating..."); 
} 

Pig.eat(); //No implementation of eat in the Pig object 

我可以保證孩子繼承了所有除了自身的那些其父對象變量的不顯式調用這樣的父類的構造:

function Pig(i) 
{ 
    User.call(this, i); 
    //Some pig-like variables 
} 

基本上,我想創建在我的父類中的所有實現,只寫需要重寫的函數+子類中的任何附加函數。如果我想調用Pig.eat(),我希望它使用父函數,如果在子對象中不存在。在創建一個Pig對象時,我希望它能夠繼承父對象的變量以及它自己的變量。這可能嗎?

+4

首先,你需要做一個'新Pig' *實例*之前,你可以調用像'eat'它的方法。並且你[不應該使用'new'來創建原型對象](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here) – Bergi

+3

不,就像在經典繼承中一樣,每次都需要顯式調用'super'(這裏:'Animal.call(this,i);')。當然,在JS中,你可以通過元編程在這裏獲得一些糖。 – Bergi

+1

*「我可以確保孩子繼承父母的功能嗎?我不需要顯式調用它們,或者在子對象中創建它們?「*看起來你只需要瞭解[原型如何工作](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/ch5.md )。我鼓勵你接受JavaScript的原型繼承,並忘記了基於類的繼承。 –

回答

2

我想在我的父類中創建所有的實現,只編寫需要重寫的函數+子類中的任何附加函數。

它實際上是這樣工作的。 也許你只是做了一個有點不對勁,看看這個例子:

//Parent 
 
function Animal() 
 
{ 
 
    this.animalInstinct = true; 
 
} 
 

 
Animal.prototype.eat = function() 
 
{ 
 
    alert("eating..."); 
 
} 
 

 
//Child 
 
function Pig() 
 
{ 
 
    this.nose = 'pigNose' 
 
} 
 

 
Pig.prototype = new Animal(); 
 

 
pig = new Pig(); 
 

 
pig.eat(); //There is implementation of eat in the Pig object

還要注意的是Pig.prototype = new Animal();可以在某些情況下是有問題的。例如,爲了定義Pig類,您需要實例化Animal對象。對於需要將一些參數傳遞給構造函數的更復雜對象,這可能不太方便。

Recommended way是要做Pig.prototype = Object.create(Animal.prototype)

1

查看ES6的方式,可以使用類似Babel的東西輕鬆編譯成ES5。

'use strict'; 
class Animal { 
    constructor() { 
    } 

    eat() { 
     console.log('Eating') 
     return this; 
    } 

    play() { 
     console.log('Do whatever an animal does...'); 
     return this; 
    } 
} 

class Pig extends Animal { 
    constructor() { 
     super() 
    } 

    play() { 
     // This overrides the Animal play method 
     console.log('Roll in the mud!'); 
     return this; 
    } 

    makeBacon() { 
     console.log('BACON!!'); 
    } 
} 

如果你想看到一個ES5版本,複製粘貼到上述通天的現場testing console,或者只是測試,在Chrome瀏覽器的最新版本,因爲它支持它。 然後,您可以執行以下操作:

var pig = new Pig(); 
pig.eat().play().eat().makeBacon();