最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript寄生組合式繼承實(shí)例詳解

 更新時(shí)間:2018年01月06日 11:01:12   作者:qq_26222859  
這篇文章主要介紹了JavaScript寄生組合式繼承,結(jié)合實(shí)例形式詳細(xì)分析了寄生組合式繼承原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了JavaScript寄生組合式繼承。分享給大家供大家參考,具體如下:

其實(shí)《JavaScript高級(jí)程序設(shè)計(jì)》這本書(shū)中已經(jīng)有完整代碼了,只要把代碼讀懂就知道這個(gè)繼承是怎么回事。

首先,在js中,給對(duì)象定義屬性有兩種方式:

//通過(guò)執(zhí)行構(gòu)造函數(shù)設(shè)置屬性
function A(){
  this.a = 1;
}
//通過(guò)原型設(shè)置屬性
A.prototype.b = 1;

所以:

一個(gè)類(lèi)Sub要繼承另一個(gè)類(lèi)Super,需要繼承父類(lèi)的prototype下的屬性,還要執(zhí)行一下父類(lèi)的構(gòu)造函數(shù)。

一個(gè)類(lèi)Sub要繼承另一個(gè)類(lèi)Super,既要通過(guò)原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,又要通過(guò)在子類(lèi)構(gòu)造函數(shù)內(nèi)調(diào)用父類(lèi)構(gòu)造函數(shù)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。

1. 繼承prototype下的屬性

上面可以看到,Super類(lèi)的prototype下的屬性是沒(méi)有被繼承的,因此下面還需要繼承這一部分。

直接「=」肯定不行,因?yàn)镾ub.prototype中修改屬性后,不能影響Super.prototype里面的對(duì)象,即不能Sub.prototype=Super.prototype

首先寫(xiě)一個(gè)創(chuàng)建對(duì)象副本的方法

function object(o){
  function A(){}
  A.prototype = o
  var ox = new A()
  return ox
}

上面的函數(shù)得到的對(duì)象ox,擁有了對(duì)象o的全部屬性(在原型鏈上),而修改ox的屬性,不會(huì)影響到o,相當(dāng)于把o復(fù)制了一份。

原型式繼承就是上面的“object”函數(shù),在很多類(lèi)庫(kù)源碼中都能發(fā)現(xiàn)它的身影

簡(jiǎn)單而言,原型式繼承就是不用實(shí)例化父類(lèi)了,直接實(shí)例化一個(gè)臨時(shí)副本實(shí)現(xiàn)了相同的原型鏈繼承。(即子類(lèi)的原型指向父類(lèi)副本的實(shí)例從而實(shí)現(xiàn)原型共享)

tips:總所周知,原型鏈繼承是子類(lèi)的原型指向父類(lèi)的實(shí)例從而實(shí)現(xiàn)原型共享,而原型式繼承是子類(lèi)的原型指向父類(lèi)副本的實(shí)例從而實(shí)現(xiàn)原型共享。

ECMAScirpt 5通過(guò)新增Object.create()方法規(guī)范化了原型式繼承。

使用object方法,就可以將Super.prototype的屬性「復(fù)制」到Sub.prototype上了,當(dāng)然這兒還需要修正一下constructor的指向。

function inherit(subType,superType){
 var prototype=Object.create(superType.prototype);
 prototype.constructor=subType;
 subType.prototype=prototype;
}

2. 分別執(zhí)行父類(lèi)和子類(lèi)的構(gòu)造函數(shù),繼承這部分下的屬性:

//父類(lèi)
function Super(){
this.sss=1
}
//子類(lèi)
function Sub(){
//arguments是Sub收到的參數(shù),將這個(gè)參數(shù)傳給Super
Super.apply(this, arguments)
}
//實(shí)例
sub = new Sub()

Super.apply(this, arguments)這一句,將Super類(lèi)作為一個(gè)普通函數(shù)來(lái)執(zhí)行,但是Super類(lèi)的this被換成了Sub類(lèi)的this,Sub收到的參數(shù)也傳給了Super

最后執(zhí)行結(jié)果相當(dāng)于sub.sss=1

附上各種繼承方式的特點(diǎn)和優(yōu)缺點(diǎn)

曾經(jīng)一段時(shí)間因?yàn)閖avascript關(guān)于類(lèi)實(shí)現(xiàn)繼承的不規(guī)范,導(dǎo)致各種各樣實(shí)現(xiàn)繼承的代碼;而實(shí)際上不管代碼怎么變,繼承都基于兩種方式:

1.通過(guò)原型鏈,即子類(lèi)的原型指向父類(lèi)的實(shí)例從而實(shí)現(xiàn)原型共享。
2.借用構(gòu)造函數(shù),即通過(guò)js的apply、call實(shí)現(xiàn)子類(lèi)調(diào)用父類(lèi)的屬性、方法;

原型鏈方式可以實(shí)現(xiàn)所有屬性方法共享,但無(wú)法做到屬性、方法獨(dú)享(例如Sub1修改了父類(lèi)的函數(shù),其他所有的子類(lèi)Sub2、Sub3...想調(diào)用舊的函數(shù)就無(wú)法實(shí)現(xiàn)了);

借用構(gòu)造函數(shù)除了能獨(dú)享屬性、方法外還能在子類(lèi)構(gòu)造函數(shù)中傳遞參數(shù),但代碼無(wú)法復(fù)用??傮w而言就是可以實(shí)現(xiàn)所有屬性方法獨(dú)享,但無(wú)法做到屬性、方法共享(例如,Sub1新增了一個(gè)函數(shù),然后想讓Sub2、Sub3...都可以用的話就無(wú)法實(shí)現(xiàn)了,只能Sub2、Sub3...各自在構(gòu)造函數(shù)中新增)。

組合繼承就是把以上兩種繼承方式一起使用,把共享的屬性、方法用原型鏈繼承實(shí)現(xiàn),獨(dú)享的屬性、方法用借用構(gòu)造函數(shù)實(shí)現(xiàn),所以組合繼承幾乎完美實(shí)現(xiàn)了js的繼承;為什么說(shuō)是“幾乎”?因?yàn)檎J(rèn)(dan)真(teng)的geek們發(fā)現(xiàn)組合繼承有一個(gè)小bug,實(shí)現(xiàn)的時(shí)候調(diào)用了兩次超類(lèi)(父類(lèi)),性能上不合格啊有木有!怎么解決呢?于是“寄生繼承”就出來(lái)了。

寄生繼承(原型式繼承)就是不用實(shí)例化父類(lèi)了,直接實(shí)例化一個(gè)臨時(shí)副本實(shí)現(xiàn)了相同的原型鏈繼承。(即子類(lèi)的原型指向父類(lèi)副本的實(shí)例從而實(shí)現(xiàn)原型共享)

“寄生組合繼承”用了“寄生繼承”修復(fù)了“組合繼承”的小bug,從而讓js完美實(shí)現(xiàn)繼承了。

實(shí)例代碼:

function SuperType(name,colors){
  this.name=name;
  this.colors=colors;
}
SuperType.prototype.getSuperProperty=function(){ return this.name; }
function SubType(job,name,colors){
  SuperType.call(this,name,colors);
  this.job=job;
}
SubType.prototype.getSubPrototype=function(){ return this.job; }
function inherit(subType,superType){
  var prototype=Object.create(superType.prototype);
  prototype.constructor=subType;
  subType.prototype=prototype;
}
inherit(SubType,SuperType);
var instance=new SubType("doctor","John",["red","green"]);
console.log(instance.getSubPrototype());  //輸出"doctor"
console.log(instance.getSuperProperty());  //輸出"John",成功調(diào)用在父類(lèi)原型定義的方法

屬性繼承代碼是SuperType.call(this,name,colors);

原型繼承代碼是inherit(SubType,SuperType);

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專(zhuān)題:《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)

希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評(píng)論

万载县| 宁安市| 红桥区| 邮箱| 永胜县| 宜黄县| 光泽县| 四子王旗| 将乐县| 公主岭市| 福建省| 常德市| 克山县| 南投县| 读书| 山阳县| 兰州市| 广昌县| 灵丘县| 嘉黎县| 姜堰市| 沙田区| 南京市| 天柱县| 朝阳县| 措勤县| 洛宁县| 新津县| 乌海市| 天长市| 威远县| 宜良县| 金塔县| 安吉县| 蒙城县| 绥阳县| 镇原县| 黄龙县| 清水县| 乌兰察布市| 六盘水市|