js繼承的這6種方式!(上)
寫在前面
繼承的簡介
繼承”是JavaScript面向?qū)ο笤O(shè)計(jì)的重要一環(huán),愿你認(rèn)真讀完本文,吃透繼承的概念。
繼承的核心
1. 繼承方式一:原型鏈
1.1 介紹
原型鏈?zhǔn)菍?shí)現(xiàn)繼承最原始的模式,即通過prototype屬性實(shí)現(xiàn)繼承。
//父級-構(gòu)造函數(shù) function Father() { this.fatherProp = true } //父級-原型屬性 Father.prototype.getFatherValue = function() { return this.fatherProp } //子級-構(gòu)造函數(shù) function Son() { this.sonProp = false } //子級-原型屬性:繼承父級 //即__proto__指向父級的prototype //若不理解請閱讀《一張圖徹底KO原型鏈(prototype,__proto__》 Son.prototype = new Father() //子級-添加原型方法 Son.prototype.getSonValue = function() { return this.sonProp } //創(chuàng)建子級的實(shí)例對象 var son = new Son() console.log(son.getFatherValue()) //true
1.2 解析:son實(shí)例對象是如何找到getFatherValue()方法的呢?
- 首先在son對象自身中找。若對象自身沒找到
- 然后在Son.prototype中找。若Son.prototype中沒找到
- 繼續(xù)往上一層,Son.prototype.__proto__(Fater.prototype)
- 依次類推,直到找到需要的屬性或方法,或到達(dá)原型鏈頂端Object.prototype
如果到最后都沒找到,會發(fā)生什么呢?
//一個(gè)不存在的方法 console.log(son.getValue()) //ERROE:not a function
1.3 注意事項(xiàng)
重寫父級原型鏈的方法或者添加父級原型鏈不存在的方法,必須在父級原型鏈代碼之后。(這個(gè)很好理解,不放代碼演示了)
通過原型鏈實(shí)現(xiàn)繼承后,不能再使用字面量的方式創(chuàng)建原型對象,因?yàn)闀采w原型鏈。
//子級-原型屬性:繼承父級 Son.prototype = new Father() //不能像下面這樣,這樣會使得上面的代碼無效 //因?yàn)檫@相當(dāng)于重新創(chuàng)建了一個(gè)原型對象 Son.prototype = { getSonValue: function() { return this.sonProp } }
1.4 原型鏈實(shí)現(xiàn)繼承的弊端
世間萬事萬物都不可能十全而十美,原型鏈雖然強(qiáng)大,但也存在缺陷。
原型鏈中引用類型的屬性會被所有實(shí)例共享的,即所有實(shí)例對象使用的是同一份數(shù)據(jù),會相互影響。
function Father() { this.arr = [1,2,3] } function Son() { } Son.prototype = new Father() var son1 = new Son() console.log(son1.arr) //1,2,3 var son2 = new Son() son2.arr.push(4) console.log(son2.arr) //1,2,3,4 console.log(son1.arr) //1,2,3,4
無法向父級構(gòu)造函數(shù)傳參
2. 繼承方式二:借用構(gòu)造函數(shù)
2.1 介紹
方式一中引用類型帶來的問題可借用構(gòu)造函數(shù)的方式解決。其核心思想是:在子級構(gòu)造函數(shù)中調(diào)用父級構(gòu)造函數(shù)。
如何實(shí)現(xiàn)在一個(gè)構(gòu)造函數(shù)中調(diào)用另一個(gè)函數(shù)?——call()和apply()
function Father() { this.arr = [1,2,3] } function Son() { //call的第一個(gè)函數(shù)是this指向的對象,即構(gòu)造函數(shù)的實(shí)例對象 Father.call(this) /*上面代碼等同于下面這段代碼: (function() { this.arr = [1,2,3] }).call(this) */ } var son1 = new Son() console.log(son1.arr) //1,2,3 var son2 = new Son() son2.arr.push(4) console.log(son2.arr) //1,2,3,4 console.log(son1.arr) //1,2,3
//解決傳參問題: function Father(name) { this.name = name } function Son(name) { Father.call(this, name) } var son1 = new Son("小名") console.log(son1.name) //小名 var son2 = new Son("一燈") console.log(son2.name) //一燈
2.2 借用構(gòu)造函數(shù)的缺陷
這種方式是通過構(gòu)造函數(shù)實(shí)現(xiàn)的,當(dāng)然也把構(gòu)造函數(shù)自身的問題帶過來了——破壞了復(fù)用性。因?yàn)槊總€(gè)實(shí)例都創(chuàng)建了一份副本。
3. 組合繼承
3.1 介紹
組合繼承 = 原型鏈 + 借用構(gòu)造函數(shù)。取其長避其短:共享的用原型鏈,各自的借用構(gòu)造函數(shù)
function Father(name) { this.name = name this.arr = [1,2,3] } Father.prototype.getName = function() { console.log(this.name) } function Son(name, age) { Father.call(this, name) this.age = age } Son.prototype = new Father() Son.prototype.constructor = Son Son.prototype.getAge = function() { console.log(this.age) } var son1 = new Son("小名", 23) son1.arr.push(4) console.log(son1.arr) //1,2,3,4 son1.getName() //小名 son1.getAge() //23 var son2 = new Son("一燈", 24) console.log(son2.arr) //1,2,3 son1.getName() //一燈 son1.getAge() //24
3.2 解析
借用構(gòu)造函數(shù)部分:
Father.call(this, name)——name來自Father
this.age = age; Son.prototype.constructor = Son——age來自Son
原型鏈部分:
Father.prototype.getName——getName方法來自Father.prototype
Son.prototype.getAge——getAge來自Son.prototype
后記
關(guān)于繼承的后三種方式馬上推出,期待你的點(diǎn)贊&關(guān)注!
以上所述是小編給大家介紹的js繼承方式詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
JavaScript開發(fā)者必備的10個(gè)Sublime Text插件
Sublime Text幾乎是任何開發(fā)者在其工具箱的必備應(yīng)用程序,這篇文章主要介紹了JavaScript開發(fā)者必備的10個(gè)Sublime Text插件,感興趣的小伙伴們可以參考一下2016-02-02javascript中RegExp保留小數(shù)點(diǎn)后幾位數(shù)的方法分享
文章介紹一篇關(guān)于javascript中RegExp保留小數(shù)點(diǎn)后幾位數(shù)方法,有需要了解的朋友可以參考一下2013-08-08JS實(shí)現(xiàn)定時(shí)自動關(guān)閉DIV層提示框的方法
這篇文章主要介紹了JS實(shí)現(xiàn)定時(shí)自動關(guān)閉DIV層提示框的方法,可實(shí)現(xiàn)加載時(shí)載入js代碼控制div層提示框自動關(guān)閉的效果,非常簡單實(shí)用,需要的朋友可以參考下2015-05-05js實(shí)現(xiàn)網(wǎng)頁定位導(dǎo)航功能
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)網(wǎng)頁定位導(dǎo)航功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03JS中如何判斷傳過來的JSON數(shù)據(jù)中是否存在某字段
這篇文章主要介紹了JS中如何判斷傳過來的JSON數(shù)據(jù)中是否存在某字段,需要的朋友可以參考下2014-08-08關(guān)于json字符串與實(shí)體之間的嚴(yán)格驗(yàn)證代碼
在一個(gè)項(xiàng)目中要求嚴(yán)格驗(yàn)證傳入的json字符串與定義的 類匹配,否則不記錄。后來查了好多資料才弄明白,下面小編給大家分享下關(guān)于json字符串與實(shí)體之間的嚴(yán)格驗(yàn)證,感興趣的朋友一起看看吧2016-11-11