? ? ? ? ? 原型繼承大概是javascript中古老又傳統(tǒng)的繼承方法了历涝,通過(guò)prototype兰迫,即可實(shí)現(xiàn)繼承薪缆,具體的用法我在之前的文章中也提到過(guò)秧廉。
? ? ? 所謂原型繼承就是利用javascript訪問(wèn)對(duì)象屬性或者方法時(shí)候會(huì)查找原型鏈這個(gè)特性,當(dāng)你創(chuàng)建父類(lèi)對(duì)象且實(shí)例賦值給子類(lèi)構(gòu)造函數(shù)的原型屬性拣帽,子類(lèi)的實(shí)例在創(chuàng)建時(shí)候都會(huì)通過(guò)__proto__查找然后與子類(lèi)構(gòu)造函數(shù).prototype的鏈接獲得父類(lèi)對(duì)象的所有屬性和方法疼电。這里要注意的是子類(lèi)對(duì)象只是從父類(lèi)繼承,這些屬性和方法并不真正的直接存在本身上减拭,而是存在其構(gòu)造函數(shù)的原型prototype對(duì)象中或者實(shí)例的__proto__屬性上蔽豺。
var Eat = function(){
? ? ? this.food = “面包”;
}拧粪;
var Person = function(){
? ? this.name = name修陡;
? ? this.action = function(){
? ? ? ? alert(“打完球感覺(jué)很餓,”+ “this.name” +“去商場(chǎng)買(mǎi)了”+ “this.food”)可霎;
}
}魄鸦;
Person.prototype = new Eat();
var person = new Person (“小明”)癣朗;
person.action()号杏;
輸出:打完球感覺(jué)很餓,小明去商場(chǎng)買(mǎi)了面包
當(dāng)Person實(shí)例person調(diào)用action()方法時(shí)候,需要找到this.food盾致,但是本身對(duì)象里沒(méi)有這個(gè)屬性,于是javascript就利用自身特性荣暮,沿著原型鏈查找庭惜,當(dāng)查找到person的構(gòu)造函數(shù)Person的prototype對(duì)象時(shí)候,發(fā)現(xiàn)了這一屬性并返回結(jié)果穗酥。
但是原型繼承并非完美的护赊,構(gòu)造函數(shù)的prototype在創(chuàng)建時(shí)候并非是完全的空對(duì)象,它里面是有一個(gè)屬性construcor砾跃,指的是它自己骏啰,如果用一個(gè)實(shí)例對(duì)象來(lái)替換函數(shù)的prototype,那這個(gè)屬性會(huì)被替換抽高,原本的constuctor屬性也隨之丟失判耕。
this.prototype ={construcor :this}
拿上面的例子來(lái)說(shuō):
輸出person的constructor:
function (){
? ? this.eat = “food”;
}
是Eat的構(gòu)造函數(shù)翘骂,Person的prototype會(huì)被Eat實(shí)例替換壁熄,那里面constructor屬性也被覆蓋。所以碳竟,如果需要保留真正的構(gòu)造器草丧,你可以在替換了Person的prototype之后再做些別的事情:
Person.prototype.constructor = Person;
這樣再訪問(wèn)person的constructor屬性時(shí)候會(huì)反回Person的構(gòu)造函數(shù)莹桅;
當(dāng)構(gòu)造器的prototype對(duì)象更新時(shí)候昌执,之前產(chǎn)生的所有實(shí)例對(duì)象也會(huì)做出立即更新:
var Eat = function(){
? ? ? this.food = “面包”;
}诈泼;
var Person = function(){
? ? this.name = name懂拾;
? ? this.action = function(){
? ? ? ? alert(“打完球感覺(jué)很渴+ “this.name” +“去商場(chǎng)喝了”+ “this.drinks);
}
}厂汗;
Person.prototype = new Eat()委粉;
var person = new Person (“小明”);
person.action()娶桦;
Person.prototype.drinks =“可樂(lè)”贾节;
person.action();
先后輸出:
打完球很渴衷畦,小明去商場(chǎng)喝了undefined
打完球很渴栗涂,小明去商場(chǎng)喝了可樂(lè)
很容易看出來(lái):
Person.prototype.drinks = “可樂(lè)”
作用等于
Eat.prototype.drinks = “可樂(lè)”
這僅僅是更新,而非把prototype換成別的對(duì)象祈争。