方法1:通過原型鏈
這種模式的問題是Dog的所有實例共享同一個Animal實例,一旦在dog1種修改Animal屬性,dog2種的Animal屬性也被修改,這是我們不想看到的,因爾這種繼承并不實用。
function Animal(){
this.Age = null;
this.Name = null;
}
Animal.prototype.Eat = function(){
console.log(this.Name + ' eat')
}
function Dog(){
this.Species = null;
}
Dog.prototype = new Animal();
var dog = new Dog();
dog.Eat()
console.log(dog);
方法2:通過call 改變this
但是這種方法仍然不完美, 每個Dog的實例中都有Eat方法,我們希望方法對于每個實例都是共享的,而不是每個實例都有一樣的方法。
function Animal(age, name){
this.Age = age;
this.Name = name;
this.Eat = function(){
console.log(this.Name + ' eat');
}
}
function Dog(species, age, name){
this.Species = species;
Animal.call(this, age, name);
}
var dog = new Dog('博美', '5', 'Jim');
console.log(dog);
方法3:組合繼承模式
這種方法結合了方法1和方法2。用原型鏈實現方法的繼承,在構造函數中實用call來實現屬性的繼承。這種方式基本完美,但是我們發現構造方法Animal被調用2次,對于追求精益求精的我們,希望有更加完美的實現。
function Animal(age, name){
this.Age = age;
this.Name = name;
}
Animal.prototype.Eat = function(){
console.log(this.Name + ' eat');
}
function Dog(species, age, name){
this.Species = species;
Animal.call(this, age, name); //第二次調用Animal()
}
Dog.prototype = new Animal(); // 第一次調用Animal()
var dog = new Dog('博美', '5', 'Jim');
dog.Eat();
console.log(dog);
方法4:寄生組合繼承模式
屬性通過call, 方法通過原型鏈,但是這種方法不會調用2次Animal(), 這種方式去掉了Animal中多余的Age和Name屬性又完美的保留的與原型鏈。
// Object.create的非規范實現
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function inheritPrototype(son, father) {
var prototype = Object.create(father.prototype)
// Object.create的實現參考上面的object
prototype.constructor = son;
// 通過Object.create生成的prototype沒有constructor,
// 所以要彌補son一個constructor
son.prototype = prototype;
// ES6 種引入了Object.setPrototypeOf, 可以省略上面的代碼直接用下面這行
//Object.setPrototypeOf(son.prototype, father.prototype);
}
function Animal(age, name){
this.Age = age;
this.Name = name;
}
Animal.prototype.Eat = function() {
console.log(this.Name + ' eat');
}
function Dog(species, age, name){
this.Species = species;
Animal.call(this, age, name);
}
inheritPrototype(Dog, Animal);
Dog.prototype.Cry = function(){
console.log(this.Name + ' cry');
}
var dog = new Dog('博美', '5', 'Jim');
dog.Eat();
dog.Cry();