首先,定義一個父類
function Father (name) {
this.name = name
this.getName = function () {
return this.name
}
this.setName = function (name) {
this.name = name
}
}
原型鏈繼承
function Son (name) {
this.name = name
}
Son.prototype = new Father()
缺點:
沒有使用Father的構造函數,也即沒有復用Father的this.name=name
所有Son的實例共享一個Father實例,它的改變會影響到所有實例
構造函數繼承
function Son () {
Father.apply(this, arguments)
}
缺點:
沒有繼承Father的原型
Father構造函數每次實例化都被調用
組合繼承
function Son () {
Father.apply(this, arguments)
}
Son.prototype = new Father()
缺點:
仍然沒有解決Father構造函數多次調用問題
原型式繼承
/**
@param {*} father
*/
function inherit(father) {
function Fn () {}
Fn.prototype = father
return new Fn()
}
var son = inherit(new Father())
原型式繼承也就是生成一個原型對象是給定對象的對象
對比:
解決了原型繼承共享的問題
缺點:
繼承的是Father實例不是原型
需要自行修改Son實例特定的屬性和方法
寄生式繼承
function inherit(father) {
function Fn () {}
Fn.prototype = father
return new Fn()
}
// 寄生函數
function Son (father, name) {
var son = inherit(father)
son.name = name
return son
}
var son = Son(new Father())
寄生式繼承就是先得到一個原型上“復制”Father的對象,然后在這個對象中添加新的需要的屬性,就像寄生在這個對象中一樣。
對比:
解決了自定屬性問題
寄生組合式繼承
function inherit(father) {
function Fn () {}
Fn.prototype = father
return new Fn()
}
function Son () {
Father.apply(this, arguments)
}
var tmp = inherit(Father.prototype)
Son.prototype = tmp
tmp.constructor = Son
寄生組合式繼承就是原型式繼承時繼承的是Father的原型而不是實例,這實現了原型繼承
同時,寄生函數使用調用Father構造函數的方式,復用構造函數
Object.create
var son = Object.create(new Father())
extends
class Son extends Father {}