2016-07-02 70 views
1

是否有可能得到DogCatAnimal繼承(不使用classextends關鍵字),而無需編輯已經被編寫的代碼,並而內保持所有的新代碼當前的構造函數功能DRY JavaScript的繼承順序是從在一個構造函數

function Animal() { 
    this.sleep = function() { 
    var hoursSleepPerNight = this.hoursSleepPerNight; 
    console.log("z".repeat(hoursSleepPerNight)); 
    } 
} 

function Dog() { 
    this.hoursSleepPerNight = 8; 
} 

function Cat() { 
    this.hoursSleepPerNight = 7; 
} 

var dog = new Dog(); 
dog.sleep(); 
// "zzzzzzzz" 
+0

'Dog.prototype = Object.create(Animal.prototype)',但請注意'sleep'是一個屬性,它不會被繼承。你可以試試'Dog.prototype = new Animal()',但要注意副作用。 – elclanrs

+0

你爲什麼要這麼做? – Bergi

+0

@Bergi,一廂情願的想法,JavaScript可以被迫像Python/Ruby我想的行爲。 – Trajanson

回答

2

JavaScript使用原型繼承,所以你可以從Animal如下繼承:

function Animal() { 
    this.sleep = function() { 
    console.log("z".repeat(this.hoursSleepPerNight)); 
    } 
} 

function Dog() { 
    this.hoursSleepPerNight = 8; 
} 
Dog.prototype = new Animal(); 
Dog.prototype.constructor = Dog; 

function Cat() { 
    this.hoursSleepPerNight = 7; 
} 
Cat.prototype = new Animal(); 
Cat.prototype.constructor = Cat; 

var dog = new Dog(); 
dog.sleep(); 

這裏是一個小提琴:https://jsfiddle.net/k0op9sb6/

如果由於某種原因,你必須在構造函數中設置的原型功能它看起來像你可能能夠使用Object.setPrototypeOf__proto__proto) - 但是這是普遍的Ÿ不推薦

function Dog() { 
    this.hoursSleepPerNight = 8; 
    Object.setPrototypeOf(this, new Animal()); // this.__proto__ = new Animal(); 
} 
+0

爲什麼'this.prototype = new Animal();'不能在Dog構造函數中移動? – Trajanson

+1

設置'this.prototype'爲你的實例添加一個屬性'prototype'。這與設置Function.prototype不同。看起來你可以通過設置'this .__ proto__'(上面更新)來獲得你正在尋找的行爲。 – lucasjackson

+1

請使用['Object.create(Animal.prototype)'而不是'new Animal'](http://stackoverflow.com/a/17393153/1048572?Benefits-of-using-Object.create-for-inheritance)正確地做到這一點,並使用Object.setPrototypeOf而不是棄用的__proto__。 – Bergi

2

不,這是不可能的(和不理智的),以保證所有繼承相關的代碼在構造函數中,如果您正在尋找原型繼承。