您好,登錄后才能下訂單哦!
這篇文章主要講解了“javascript的繼承方式有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“javascript的繼承方式有哪些”吧!
javascript中的繼承方式有原型鏈繼承、借用構(gòu)造函數(shù)繼承、組合繼承、原型式繼承、寄生式繼承和寄生組合式繼承。其中組合繼承是我們平時最常用的一種繼承方式。
本文操作環(huán)境:windows10系統(tǒng)、javascript 1.8.5、thinkpad t480電腦。
在javascript中如果想要繼承,那么我們就必須先提供一個父類,我們這里以Person來作為父類。
下文中所有構(gòu)造函數(shù)名均無實際意義,如Coder、Rocker等,僅用于舉例
function Person(name){//給構(gòu)造函數(shù)添加了參數(shù) this.name=name; this.sex="male"; this.say=function(){ console.log(this.name); } } Person.prototype.age=21;//給構(gòu)造函數(shù)添加了原型屬性
一、原型鏈繼承
function Programmer(){ this.name="Jayee"; } Programmer.prototype=new Person();//子類構(gòu)造函數(shù).prototype=父類實例 var per1=new Programmer(); console.log(per1);//Programmer {name: "Jayee"} console.log(per1.sex);//male console.log(per1.age);//21 console.log(per1 instanceof Person);//true
重點:讓新實例的原型等于父類的實例。Programmer.prototype=new Person();
特點:實例可繼承的屬性有:實例的構(gòu)造函數(shù)的屬性,父類構(gòu)造函數(shù)屬性,父類原型 的 屬性。(新實例不會繼承父類實例的屬性!)
缺點:1、新實例無法向父類構(gòu)造函數(shù)傳參。
2、繼承單一。
3、所有新實例都會共享父類實例的屬性。(原型上的屬性是共享的,一個實例修
改了原型的屬性(per1.__proto__.sex=“female”,則per2.sex也會變成female),另
一個實例的原型屬性也會被修改?。?/p>
二、借用構(gòu)造函數(shù)繼承
//借用構(gòu)造函數(shù)繼承 function Coder(){ Person.call(this,"Jayee");//重點:借用了Person this.age=18; } var cod1=new Coder(); console.log(cod1); //Coder {name: "Jayee", sex: "male", hobby: "", age: 18, say: ?} console.log(cod1.name);//Jayee console.log(cod1.age);//18 console.log(cod1 instanceof Person);//false
重點:用.call()和.apply()將父類構(gòu)造函數(shù)引入子類函數(shù)(在子類函數(shù)中做了父類函數(shù)的自執(zhí)行(復(fù)制))
特點:1、只繼承了父類構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性。(由
cod1.age是18而不是21可看出)
2、解決了原型鏈繼承缺點1、2、3。
3、可以繼承多個構(gòu)造函數(shù)屬性(call多個)。
4、在子實例中可向父實例傳參。
缺點:1、只能繼承父類構(gòu)造函數(shù)的屬性。
2、無法實現(xiàn)構(gòu)造函數(shù)的復(fù)用。(每次用每次都要重新調(diào)用)
3、每個新實例都有父類構(gòu)造函數(shù)的副本,臃腫。
三、組合繼承(組合原型鏈繼承和借用構(gòu)造函數(shù)繼承)(常用)
//組合繼承 function Typer(name){ Person.call(this,name); } Typer.prototype=new Person(); var typ=new Typer("Jayee"); console.log(typ); //Typer {name: "Jayee", sex: "male", hobby: "", say: ?} console.log(typ.name);//Jayee,繼承了構(gòu)造函數(shù) console.log(typ.age);//21,繼承了父類的原型的屬性
重點:結(jié)合了兩種模式的優(yōu)點,傳參和復(fù)用
特點:1、可以繼承父類原型上的屬性,可以傳參,可復(fù)用。
2、每個新實例引入的構(gòu)造函數(shù)屬性是私有的。
缺點:調(diào)用了兩次父類構(gòu)造函數(shù)(耗內(nèi)存),子類的構(gòu)造函數(shù)會代替原型上的那
個父類構(gòu)造函數(shù)
四、原型式繼承
//原型式繼承 function Rocker(obj) { //先封裝一個函數(shù)容器,用來輸出對象和承載繼承的原型 function F(){} F.prototype=obj;//繼承了傳入的函數(shù) return new F();//返回函數(shù)對象 } var per=new Person();//拿到父類實例 var roc =Rocker(per);//F {} console.log(per.__proto__);//{age: 21, constructor: ?} console.log(roc.age);//21,繼承了父類函數(shù)的屬性
重點:用一個函數(shù)包裝一個對象,然后返回這個函數(shù)的調(diào)用,這個函數(shù)就變成了個可以隨
意增添屬性的實例或?qū)ο?。object.create()就是這個原理。
特點:類似于復(fù)制一個對象,用函數(shù)來包裝。
缺點:1、所有實例都會繼承原型上的屬性。
2、無法實現(xiàn)復(fù)用。(新實例屬性都是后面添加的)
五、寄生式繼承
//寄生式繼承 function Rocker(obj){ function F(){} F.prototype=obj;//繼承了傳入的函數(shù) return new F();//返回函數(shù)對象 } var per4=new Person(); //以上是原型式繼承,給原型式繼承再套個殼子傳遞參數(shù) function Artist(obj){ var roc=Rocker(obj); roc.name="Jayee"; return roc; } var art = Artist(per4) //這個函數(shù)經(jīng)過聲明之后就成了可增添屬性的對象 console.log(typeof Artist);//function console.log(typeof art);//object console.log(art.name);//Jayee,返回了個roc對象,繼承了roc的屬性
重點:就是給原型式繼承外面套了個殼子。
優(yōu)點:沒有創(chuàng)建自定義類型,因為只是套了個殼子返回對象(這個),這個函數(shù)順理成章就成了創(chuàng)建的新對象。
缺點:沒用到原型,無法復(fù)用。
六、寄生組合式繼承(常用)
寄生:在函數(shù)內(nèi)返回對象然后調(diào)用
組合:1、函數(shù)的原型等于另一個實例。2、在函數(shù)中用apply或者call引入另一個構(gòu)造函數(shù),可傳參
//寄生式組合式繼承 //寄生 function Rocker(obj){ function F(){} F.prototype=obj;//繼承了傳入的函數(shù) return new F();//返回函數(shù)對象 } //Rocker就是F實例的另一種表示法 var roc=new Rocker(Person.prototype); //roc實例(F實例)的原型繼承了父類函數(shù)的原型 //上述更像是原型鏈繼承,只不過繼承了原型屬性 //組合 function Sub(){ Person.call(this); //這個繼承了父類構(gòu)造函數(shù)的屬性 //解決了組合式兩次調(diào)用構(gòu)造函數(shù)屬性的缺點 } //重點 Sub.prototype=roc;//繼承了roc實例 roc.constructor=Sub;//一定要修復(fù)實例 var sub1=new Sub(); //Sub的實例就繼承了構(gòu)造函數(shù)屬性,父類實例,roc的函數(shù)屬性 console.log(sub1.age);//21
重點:修復(fù)了組合繼承的問題
七、ES6中的Class和extends
//todo
感謝各位的閱讀,以上就是“javascript的繼承方式有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對javascript的繼承方式有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。