繼承的幾種方式
- 原型鏈
/**
* 原型鏈繼承
* 本質(zhì)是重寫原型對象
* 缺點:引用類型值被實例共享
* @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]
原型鏈?zhǔn)疽鈭D:

- 構(gòu)造函數(shù)
/**
* 借用構(gòu)造函數(shù)模式
* 問題:函數(shù)無法復(fù)用
* @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"]
- 組合繼承(將原型鏈和構(gòu)造函數(shù)組合在一起)
/**
* 組合模式繼承
* 最常用的模式
* @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('日暮途遠(yuǎn)', 18);
let sc1 = new SubCombination('Tiptoe', 20);
sc.color.push('black');
console.log(sc.color, sc.getName(), sc.sayAge()) // ["red", "yellow", "black"] "日暮途遠(yuǎn)" 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: '日暮途遠(yuǎn)',
sayName: function () {
return this.name;
},
game: ['英雄聯(lián)盟', '王者榮耀']
}
var o = Object.create(person);
console.log(o.sayName()); // 日暮途遠(yuǎn)
o.game.push('戰(zhàn)地')
console.log(person.game) // ["英雄聯(lián)盟", "王者榮耀", "戰(zhàn)地"]
- 寄生式組合繼承
/**
* 寄生組合式繼承
* 優(yōu)點:避免2次調(diào)用父類構(gòu)造函數(shù)
* @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('日暮途遠(yuǎn)', 18)
console.log(sI.sayName()) // 日暮途遠(yuǎn)
引用
javascript高級程序設(shè)計第三版