前言:了解熊師傅的朋友都知道亏吝,百度能查的到東西絕對(duì)不會(huì)提及太多,但是如果能按照思路仔細(xì)揣摩相信你一定不會(huì)后悔的盏混,接下來(lái)開始我的表演蔚鸥。
三分鐘徹悟?哈哈哈许赃。止喷。。
原型鏈自不必說(shuō)是js前期最晦澀難懂的地方混聊,也是基礎(chǔ)中的基礎(chǔ)弹谁,是每一位前端必須有所了解的。
別怕句喜,熊師傅帶你來(lái)干 ^ . ^
一.原型鏈繼承
function aaa (name) {
this.name = name;
}
aaa.prototype.getName = function () {
return this.name;
}
function bbb (name) {
}
bbb.prototype = new aaa(‘我是哈哈’);
核心代碼: bbb.prototype = new aaa()
將bbb的原型指向aaa的實(shí)例预愤,aaa的屬性和原型方法都將掛載到bbb的原型下面。
缺點(diǎn):
1.bbb無(wú)法給aaa(父類)的構(gòu)造函數(shù)傳遞參數(shù) (無(wú)法繼承構(gòu)造函數(shù))
2.如果bbb的構(gòu)造函數(shù)也有name屬性咳胃,依然會(huì)在原型上繼承aaa的name屬性植康,造成內(nèi)存浪費(fèi)
二.借用構(gòu)造函數(shù)繼承
function aaa () {
this.name = name;
}
aaa.prototype.getName = function () {
return this.name;
}
function bbb (name, age) {
aaa.apply(this, name);
this.age = age;
}
var oBBB = new bbb();
核心代碼: aaa.apply(this, name)
在new bbb() 的 時(shí)候調(diào)用aaa,借用aaa的構(gòu)造函數(shù)展懈。
缺點(diǎn):
1.無(wú)法做到函數(shù)復(fù)用(說(shuō)白了销睁,沒(méi)有prototype)
三.組合繼承
function aaa () {
this.name = name;
}
aaa.prototype.getName = function () {
return this.name;
}
function bbb (name, age) {
aaa.apply(this, name);
this.age = age;
}
bbb.prototype = new aaa();
var oBBB = new bbb();
什么是組合繼承?
說(shuō)白了存崖,就是把前面兩種繼承方式結(jié)合起來(lái)
核心代碼:
aaa.apply(this, name);
bbb.prototype = new aaa();
思路:bbb通過(guò)call借用aaa的構(gòu)造函數(shù)冻记,并將aaa的屬性和原型方法掛載在自己的原型上面。
缺點(diǎn):
1.依然會(huì)造成內(nèi)存浪費(fèi)来惧,會(huì)把a(bǔ)aa的屬性也寫到bbb的原型上面去冗栗。
四.原型式繼承
先好好揣摩下這個(gè)東西
function object (o) {
function F () {}
F.prototype = o;
return new F();
}
那么這種模式怎么繼承呢?
var aaa = {
name: 'xxx',
age: '18',
}
var aaa1 = object(aaa);
var aaa2 = object(aaa);
很顯然aaa1和aaa2的原型上面都會(huì)有name和age屬性。
當(dāng)然缺點(diǎn)也很明顯了:
1.構(gòu)造函數(shù)和prototype不分贞瞒,所有實(shí)例的原型引用一致偶房,容易造成重寫趁曼,和原型鏈繼承的缺點(diǎn)一樣
五.寄生式繼承
說(shuō)白了军浆,對(duì)原型式繼承做了一次改造。先看看如下東西:
function createAnother (obj) {
var clone = object(obj);
clone.sayHi = function() {
alert('hi');
}
return clone;
}
var aaa = {
name: '111',
age: '2',
};
var aaa1 = createAnother(aaa);
缺點(diǎn):
1.構(gòu)造函數(shù)無(wú)法復(fù)用挡闰,也無(wú)法接受參數(shù)乒融。(其實(shí)有改造空間,把createAnother通過(guò)閉包再封裝一層摄悯,不過(guò)個(gè)人不推薦再改造)
六.寄生組合式繼承
堪稱最完美的方式:
// 這個(gè)命名牛逼不赞季? in her it ,老鐵奢驯,意會(huì) ^.^
function inherit (sub, sup) {
var prototype = object(sup.prototype);
prototype.constructor = sub;
sub.prototype = prototype;
}
function aaa (name) {
this.name = name;
}
aaa.prototype.getName = function () {
alert('111');
}
function bbb (name, age) {
aaa.call(this, name);
this.age = age;
}
inherit(bbb, aaa);
bbb.prototype.xixi = function() {
alert('xixi');
}
到這里基本上解決了所有的問(wèn)題申钩,perfect。具體的工作原理瘪阁,前5種繼承方式如果認(rèn)真研究過(guò)一遍了撒遣,基本上無(wú)需再解釋,若看不懂回過(guò)頭來(lái)再溫習(xí)一遍管跺,熊師傅對(duì)于這一塊也是來(lái)回研究了十來(lái)遍才咯知一二义黎。
但是。
熊師傅對(duì)于第六種繼承方式提出一些大家可能會(huì)有的疑惑豁跑。
1.不是一樣子類繼承父類之后廉涕,父類的prototype依然會(huì)共享,同一個(gè)引用依然會(huì)改變父類的原型呀艇拍?
2.inherit有什么意義狐蜕? 和 sub.prototype = sup.prototype有什么區(qū)別?為什么非要通過(guò)object方法卸夕?
說(shuō)實(shí)話馏鹤,作者在這里也琢磨了一段時(shí)間,算是有一些自己的見(jiàn)解娇哆。如有不對(duì)湃累,歡迎指正
1.好好想一想我們?yōu)槭裁匆^承?不就是為了復(fù)用嗎碍讨?如果不是同一個(gè)引用治力,那繼承又有什么意義?(是不是有點(diǎn)恍然大悟的意思^.^)
2.這里通過(guò)inherit會(huì)重新指正子類sub的構(gòu)造函數(shù)勃黍,如果簡(jiǎn)單的 sub.prototype = sup.prototype, sub.prototype.constructor = sub 會(huì)影響父類sup.