题目:ES5 中常用继承方法。
方法一:绑定构造函数
缺点:不能继承父类原型方法/属性
1 2 3 4 5 6 7 8 9 10 11 12
| function Animal() { this.species = "动物"; } function Cat() { Animal.apply(this, arguments); }
var cat = new Cat(); console.log(cat.species);
|
方法二:原型链继承
缺点:无法向父类构造函数中传递参数;子类原型链上定义的方法有先后顺序问题。
注意:js 中交换原型链,均需要修复prototype.constructor
指向问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function Animal(species) { this.species = species; } Animal.prototype.func = function() { console.log("Animal"); }; function Cat() {}
Cat.prototype.func = function() { console.log("Cat"); }; Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;
var cat = new Cat(); cat.func(); console.log(cat.species);
|
方法 3:组合继承
结合绑定构造函数和原型链继承 2 种方式,缺点是:调用了 2 次父类的构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function Animal(species) { this.species = species; } Animal.prototype.func = function() { console.log("Animal"); }; function Cat() { Animal.apply(this, arguments); } Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;
var cat = new Cat("cat"); cat.func(); console.log(cat.species);
|
方法 4:寄生组合继承
改进了组合继承的缺点,只需要调用 1 次父类的构造函数。它是引用类型最理想的继承范式。(引自:《JavaScript 高级程序设计》)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
function inheritPrototype(sub, parent) { var prototype = Object.create(parent.prototype); prototype.constructor = sub; sub.prototype = prototype; } function Animal(species) { this.species = species; } Animal.prototype.func = function() { console.log("Animal"); }; function Cat() { Animal.apply(this, arguments); } inheritPrototype(Cat, Animal);
var cat = new Cat("cat"); cat.func(); console.log(cat.species);
|