(文章僅用于梳理繼承知識(shí)點(diǎn),想深入了解需要看書)
我們知道燎竖,面向?qū)ο蟮娜筇匦裕悍庋b璃弄、繼承、多態(tài)构回。講到繼承夏块,在現(xiàn)實(shí)中,有子承父業(yè)的說法捐凭,大概意思是兒子擁有了父親的一切拨扶。在javascript中凳鬓,如果對(duì)象a能訪問到對(duì)象b的所有屬性和方法茁肠,我們就可以說a繼承b。
相比于java的類繼承缩举,javascript中一般使用原型鏈來實(shí)現(xiàn)繼承垦梆。回顧下原型仅孩、實(shí)例托猩、構(gòu)造函數(shù)的三者關(guān)系。當(dāng)實(shí)例對(duì)象訪問一個(gè)變量時(shí)辽慕,如果在當(dāng)前實(shí)例中找不到相應(yīng)的標(biāo)志符京腥,則會(huì)在原型對(duì)象中查找。想象一下溅蛉,如果原型對(duì)象是另一個(gè)類型的實(shí)例呢公浪?那么在當(dāng)前原型對(duì)象搜索不到結(jié)果時(shí)他宛,會(huì)到另一個(gè)類型的原型對(duì)象上查找,如此下來欠气,便形成了一個(gè)鏈狀結(jié)構(gòu)厅各。 因而,就本質(zhì)而言预柒,javascript通過重寫原型來實(shí)現(xiàn)繼承队塘。
function Super(){
this.type='super'
}
Super.prototype.getType = function(){
return this.type
}
function Sub(){
this.type = 'sub'
}
Sub.prototype = new Super()
Sub.prototype.name = 'sub'
var a = new Sub()
a.type//sub
a.getType()//sub
常言說,青出于藍(lán)而勝于藍(lán)宜鸯。在javascript中的體現(xiàn)則是重寫原型方法憔古。
function Super(){
this.type='super'
}
Super.prototype.getType = function(){
return this.type
}
function Sub(){
}
Sub.prototype = new Super()
Sub.prototype.getType = function(){
return 'new type:'+this.type
}
var a = new Sub()
a.getType()//new type:super
單純的原型方法來實(shí)現(xiàn)繼承時(shí),會(huì)有一個(gè)問題顾翼。由于用了原型投放,所以原型方法會(huì)被所有實(shí)例共享的問題也會(huì)暴露。由于由于重寫原型鏈的緣故适贸,父類型的實(shí)例屬性變成字類型實(shí)例對(duì)象的原型屬性灸芳。
于是,我們可以借用構(gòu)造函數(shù)來避免這一點(diǎn)拜姿。
function Super(){
this.child=['a','b','c']
}
Super.prototype.getChild = function(){
return this.child
}
function Sub(){
Super.apply(this,arguments)
}
var a = new Sub()
var b = new Sub()
a.child.push('d')
b.child//['a','b','c']
然而單純的構(gòu)造函數(shù)則無法繼承父類型的原型方法和屬性烙样。因而在實(shí)例情景中,我們往往兩者結(jié)合蕊肥。構(gòu)造函數(shù)負(fù)責(zé)處理父類型實(shí)例屬性和方法谒获,原型則處理父類型原型屬性和方法。為了避免兩次調(diào)用父類型構(gòu)造函數(shù)(第一次在子類型原型賦值給父類型的實(shí)例化對(duì)象壁却,第二次是實(shí)例子類型時(shí)批狱,借用了父類型構(gòu)造函數(shù)),我們會(huì)引入一個(gè)中間函數(shù)來做過渡展东。(寄生組合繼承)
function Sup(){
this.type='sup'
}
Sup.prototype.getType = function(){
return this.type
}
function f(){}
f.prototype = Sup.prototype
function Sub(){
Sup.apply(this,arguments)
this.type = 'sub'
}
Sub.prototype = new f()
var a= new Sub()
a.getType()
由于這些繼承方式寫法繁瑣赔硫,所以es6制定了一個(gè)語法糖。我們可以像寫java繼承的方式來寫javascript繼承
class Sup{
constructor(){
this.type='sup'
}
getType(){
return this.type
}
}
class Sub extends Sup{
constructor(){
super()
this.name = 'a'
}
getType(){
return 'a'
}
}
var a = new Sub()
注意點(diǎn):如果要重寫子類型的構(gòu)造函數(shù)盐肃,需要先調(diào)用super方法爪膊。