继承的几种方式
- 原型链
/**
* 原型链继承
* 本质是重写原型对象
* 缺点:引用类型值被实例共享
* @constructor
*/
function Super() {
this.property = 'super'
this.arr = [1,2]
}
Super.prototype.getValue = function () {
return this.property
}
function Sub() {
}
Sub.prototype = new Super();
let sub = new Sub()
console.log(sub.getValue()) // super
console.log(Super.prototype.isPrototypeOf(sub)) // true
console.log(Sub.prototype.isPrototypeOf(sub)) // true
console.log(Object.prototype.isPrototypeOf(sub)) // true
let sub1 = new Sub()
sub1.arr.push(3);
let sub2 = new Sub()
console.log(sub1.arr) // [1,2,3]
console.log(sub2.arr) // [1,2,3]
原型链示意图:
- 构造函数
/**
* 借用构造函数模式
* 问题:函数无法复用
* @constructor
*/
function SuperInstance() {
this.color = ['red', 'yellow']
}
function SubInstance() {
SuperInstance.call(this)
}
var si = new SubInstance();
var si1 = new SubInstance();
si.color.push("black");
console.log(si.color) // ["red", "yellow", "black"]
console.log(si1.color) // ["red", "yellow"]
- 组合继承(将原型链和构造函数组合在一起)
/**
* 组合模式继承
* 最常用的模式
* @param name
* @constructor
*/
function SuperCombination(name) {
this.name = name;
this.color = ['red', 'yellow'];
}
SuperCombination.prototype.getName = function () {
return this.name;
}
function SubCombination(name, age) {
SuperCombination.call(this, name)
this.age = age
}
SubCombination.prototype = new SuperCombination();
// SubCombination.prototype.constructor = SubCombination;
SubCombination.prototype.sayAge = function () {
return this.age;
}
let sc = new SubCombination('日暮途远', 18);
let sc1 = new SubCombination('Tiptoe', 20);
sc.color.push('black');
console.log(sc.color, sc.getName(), sc.sayAge()) // ["red", "yellow", "black"] "日暮途远" 18
console.log(sc1.color, sc1.getName(), sc1.sayAge()) // ["red", "yellow"] "Tiptoe" 20
- 原型式继承
/**
* 原型式继承
* 缺点: 引用类型共享
* @type {{name: string, sayName: person.sayName, game: [string,string]}}
*/
var person = {
name: '日暮途远',
sayName: function () {
return this.name;
},
game: ['英雄联盟', '王者荣耀']
}
var o = Object.create(person);
console.log(o.sayName()); // 日暮途远
o.game.push('战地')
console.log(person.game) // ["英雄联盟", "王者荣耀", "战地"]
- 寄生式组合继承
/**
* 寄生组合式继承
* 优点:避免2次调用父类构造函数
* @param subType
* @param superType
*/
function inherit(subType, superType) {
var property = Object.create(superType.prototype);
property.constructor = subType;
subType.prototype = property;
}
function SuperIn(name) {
this.name = name
}
SuperIn.prototype.sayName = function () {
return this.name;
}
function SubIn(name, age) {
SuperIn.call(this, name)
this.age = age
}
inherit(SubIn, SuperIn)
SubIn.prototype.sayAge = function () {
return this.age;
}
let sI = new SubIn('日暮途远', 18)
console.log(sI.sayName()) // 日暮途远
引用
javascript高级程序设计第三版