- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) > JavaScript >
- 原生Javascript實(shí)現繼承方式及其優(yōu)缺點(diǎn)詳解
最近在復習javascript的一些基礎知識,為開(kāi)啟新的征程做準備。所以開(kāi)始記錄一些自己學(xué)習的內容。
那今天的主題是 js的原生繼承方式
廢話(huà)少說(shuō),上代碼!
首先是我們的父類(lèi)代碼。
在這里我們創(chuàng )建一個(gè)Person的類(lèi)作為父類(lèi),它的構造函數需要2個(gè)參數name和age。
然后我們在它的原型上添加一個(gè)sayHi的方法。
//父類(lèi) function Person (name, age) { this.name = name || 'no name'; this.age = age || 0; } Person.prototype.sayHi = function () { console.log('Hi, I\'m ' + this.name + ' and i\'m ' + this.age + ' years old!'); } var p = new Person('A',20); p.sayHi();//Hi, I'm A and i'm 20 years old!
//原型繼承 function Teacher(){ } Teacher.prototype=new Person('B',22); Teacher.prototype.constructor=Teacher; var t = new Teacher(); t.sayHi();//Hi, I'm B and i'm 22 years old! console.log(t instanceof Person);//true console.log(t instanceof Teacher);//true
從上面的代碼來(lái)看,Teacher 的實(shí)例擁有了 Person 的屬性和方法。并且實(shí)例對象既是 Person的實(shí)例也是 Teacher的實(shí)例。而且這種繼承方式特別的簡(jiǎn)單。
我們可以很容易的就發(fā)現Teacher類(lèi)的 name和 age是固定的,都是name=B和age=22,換句話(huà)說(shuō)就是我們無(wú)法實(shí)現按照我們的意愿給父類(lèi)的構造函數傳參。并且一個(gè)我們不能給一個(gè) Teacher 指定多個(gè)原型,也就是沒(méi)法 多繼承。然后我們看下下面這段代碼:
var t1 = new Teacher(); var t2 = new Teacher(); Teacher.prototype.name = "C"; t1.sayHi();//Hi, I'm C and i'm 22 years old! t2.sayHi();//Hi, I'm C and i'm 22 years old!
上面這段代碼中我們可以看到當原型中的屬性或者方法被改變時(shí),所有的子類(lèi)實(shí)例的屬性和方法也會(huì )跟著(zhù)被改變,也就是原型繼承的另一個(gè)缺點(diǎn):所有子類(lèi)共享同一個(gè)原型對象
這里說(shuō)到了原型,我很早之前也寫(xiě)過(guò)一個(gè)關(guān)于原型的隨筆,不過(guò)可能也是有些模糊,現在的理解和當時(shí)有所不同,我會(huì )在后面重新寫(xiě)一篇關(guān)于原型的隨筆。(寫(xiě)好了我會(huì )附上連接)
//構造函數繼承 function Teacher (name, age) { Person.call(this, name, age); } var t1 = new Teacher('B', 22); var t2 = new Teacher('C', 30); console.log(t1.name);//B console.log(t2.name);//C console.log(t1 instanceof Person);//false console.log(t1 instanceof Teacher);//true t1.sayHi();//TypeError: t1.sayHi is not a function t2.sayHi();//TypeError: t1.sayHi is not a function
相對于 原型繼承 , 構造函數繼承解決了所有的子類(lèi)實(shí)例共享統一原型的問(wèn)題,也可以給父類(lèi)的構造函數傳參,并且我們可以在子類(lèi)的構造函數中調用多個(gè)父類(lèi)的構造函數,實(shí)現所謂的多繼承(這里的多繼承是指子類(lèi)通過(guò)call,apply等方法去調用父類(lèi)的構造函數使其擁有父類(lèi)的屬性和方法,但是js中一個(gè)函數對象只存在一個(gè) prototype,所以其實(shí)我們沒(méi)法通過(guò)原型鏈的形式去體現出多繼承)
上面的代碼中我們可以看出創(chuàng )建的實(shí)例只是 子類(lèi)的實(shí)例 并不是 父類(lèi)的實(shí)例 ,不能直觀(guān)的體現出繼承,這種繼承方式也無(wú)法繼承父類(lèi)的原型上的屬性和方法。
//組合式繼承 function Teacher (name, age) { Person.call(this, name, age); } Teacher.prototype = new Person(); Teacher.prototype.constructor = Teacher; var t1 = new Teacher('B', 22); var t2 = new Teacher('C', 30); Teacher.prototype.name = "D"; console.log(t1.name);//B console.log(t2.name);//C t1.sayHi();//Hi, I'm B and i'm 22 years old! t2.sayHi();//Hi, I'm C and i'm 30 years old! console.log(t1 instanceof Person);//true console.log(t1 instanceof Teacher);//true
組合式繼承就是結合了原型繼承和構造函數繼承的優(yōu)點(diǎn),解決了兩種方式存在的一些缺點(diǎn)。但是我們會(huì )發(fā)現每當我們去創(chuàng )建一個(gè)子類(lèi)實(shí)例的時(shí)候都會(huì )去創(chuàng )建一個(gè)父類(lèi)的實(shí)例,盡管父類(lèi)實(shí)例不是同一個(gè)實(shí)例(內存地址不一樣),但是他們其實(shí)屬性和方法上完全一致,所以我們通過(guò)下面這種(寄生式組合繼承)方式完善它,以避免不必要的實(shí)例構造。
//寄生式組合繼承 function Teacher (name, age) { Person.call(this, name, age); } Teacher.prototype = Object.create(Person.prototype); Teacher.prototype.constructor = Teacher; var t1 = new Teacher('B', 22); var t2 = new Teacher('C', 30); Teacher.prototype.name = "D"; console.log(t1.name);//B console.log(t2.name);//C t1.sayHi();//Hi, I'm B and i'm 22 years old! t2.sayHi();//Hi, I'm C and i'm 30 years old! console.log(t1 instanceof Person);//true console.log(t1 instanceof Teacher);//true
上面的方式解決了我們沒(méi)創(chuàng )建一個(gè)子類(lèi)實(shí)例都去創(chuàng )建一個(gè)父類(lèi)實(shí)例的問(wèn)題,這也是最為常用的一種js的繼承方式,如果我們通過(guò)Babel去把ES6中的class的繼承轉成ES5的代碼,我們會(huì )發(fā)現就是用的寄生式組合繼承。
到此這篇關(guān)于原生Javascript實(shí)現繼承方式及其優(yōu)缺點(diǎn)的文章就介紹到這了,更多相關(guān)原生Javascript繼承方式內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站