對于JavaScript繼承你到底了解多少
前言
關(guān)于繼承,你到底了解多少,什么樣的繼承是最最優(yōu)的,讓我們一起來學(xué)習(xí)一些關(guān)于繼承的那些知識點,帶你了解他們的實現(xiàn)過程,以及他們的優(yōu)缺點
構(gòu)造函數(shù),原型對象,實例對象三者之間的關(guān)系
先來了解他們的關(guān)系有助于對繼承更好的理解
原型鏈繼承
核⼼:將⽗類實例作為⼦類原型
代碼實現(xiàn)過程:
function Parent(name){ this.name = name || 'xt', this.arr = [1] } function Son(age){ this.age = age } Parent.prototype.say = function() { //將需要復(fù)⽤、共享的⽅法定義在⽗類原型上 console.log('hello'); } Son.prototype = new Parent() let s1 = new Son(18) let s2 = new Son(19) console.log(s1.say() === s2.say()); //true console.log(s1.name,s1.age); //xt 18 console.log(s2.name,s2.age); //xt 19 s1.arr.push(2) console.log(s1.arr,s2.arr); // [ 1, 2 ] [ 1, 2 ]
優(yōu)點:
實例可繼承的屬性有:實例的構(gòu)造函數(shù)的屬性,父類構(gòu)造函數(shù)屬性,父類原型的屬性。(新實例不會繼承父類實例的屬性!)
缺點:
- ⼦類實例共享了⽗類構(gòu)造函數(shù)的引⽤屬性,⽐如arr屬性(原型上的屬性是共享的,一個實例修改了原型屬性,另一個實例的原型屬性也會被修改!)
- 不能向⽗類構(gòu)造函數(shù)傳參
借⽤構(gòu)造函數(shù)繼承
核心:借⽤⽗類的構(gòu)造函數(shù)來增強⼦類實例,等于是復(fù)制⽗類的實例屬性給⼦類
代碼實現(xiàn):
function Parent(name) { this.name = name; this.arr = [1], this.say = function() { console.log('hello') } } function Son(name, age) { Parent.call(this, name) // 拷⻉了⽗類的實例屬性和⽅法 this.age = age } let s1 = new Son('小譚', 18) let s2 = new Son('小明', 19) console.log(s1.say === s2.say) //false ⽅法不能復(fù)⽤ ⽅法是獨⽴,不是共享的 console.log(s1.name, s1.age); //小譚 18 console.log(s2.name, s2.age); //小明 19 s1.arr.push(2) console.log(s1.arr, s2.arr); // [ 1, 2 ] [ 1 ]
優(yōu)點:
- 只繼承了父類構(gòu)造函數(shù)的屬性,沒有繼承父類原型的屬性。
- 可以繼承多個構(gòu)造函數(shù)屬性(call多個)
- 在子實例中可向父實例傳參。
缺點:
- 只能繼承父類構(gòu)造函數(shù)的屬性。
- 無法實現(xiàn)構(gòu)造函數(shù)的復(fù)用。(每次用每次都要重新調(diào)用)
- 每個新實例都有父類構(gòu)造函數(shù)的副本,臃腫。
原型式繼承
核心:用一個函數(shù)包裝一個對象,然后返回這個函數(shù)的調(diào)用,這個函數(shù)就變成了個可以隨意增添屬性的實例或?qū)ο?/p>
function Parent(name) { this.name = 'xt'; this.arr = [1] } function object(obj){ function F(){} F.prototype = obj; return new F(); } let s1 = new Parent(object) s1.name = '小明' s1.arr.push(2) let s2 = new Parent(object) console.log(s1.name,s2.name); // 小明 xt console.log(s1.arr, s2.arr); //[ 1, 2 ] [ 1 ]
缺點:
- 所有實例都會繼承原型上的屬性,無法傳遞參數(shù)
- 無法實現(xiàn)復(fù)用。(新實例屬性都是后面添加的)
寄生式繼承
核心:在原型式繼承的基礎(chǔ)上,增強對象,返回構(gòu)造函數(shù)
function Parent(name) { this.name = 'xt'; this.arr = [1] } function object(obj){ function F(){} F.prototype = obj; return new F(); } let Son = new Parent() function addobject(obj){ var add = object(obj) add.name = '小白' return add } var s1 = addobject(Son) console.log(s1.name); //小白
缺點:
- 沒用到原型,無法復(fù)用。
- 原型鏈繼承多個實例的引用類型屬性指向相同,存在篡改的可能。
組合繼承(組合原型鏈繼承和借用構(gòu)造函數(shù)繼承)
核心:通過調(diào)⽤⽗類構(gòu)造函數(shù),繼承⽗類的屬性并保留傳參的優(yōu)點;然后通過將⽗類實例作為⼦類原型,實現(xiàn)函數(shù)復(fù)⽤。
代碼實現(xiàn):
function Parent(name) { this.name = name; this.arr = [1] } Parent.prototype.say = function () { console.log('hello') } function Son(name, age) { Parent.call(this, name) // 二次 this.age = age } Parent.prototype = new Son() // 一次 let s1 = new Son('小譚', 18) let s2 = new Son('小明', 19) console.log(s1.say === s2.say) // true console.log(s1.name, s1.age); //小譚 18 console.log(s2.name, s2.age); //小明 19 s1.arr.push(2) console.log(s1.arr, s2.arr); // [ 1, 2 ] [ 1 ] 不共享⽗類的引⽤屬性,
優(yōu)點:
- 保留構(gòu)造函數(shù)的優(yōu)點:創(chuàng)建⼦類實例,可以向⽗類構(gòu)造函數(shù)傳參數(shù)。
- 保留原型鏈的優(yōu)點:⽗類的⽅法定義在⽗類的原型對象上,可以實現(xiàn)⽅法復(fù)⽤。
- 不共享⽗類的引⽤屬性。⽐如arr屬性
缺點:
- 由于調(diào)⽤了2次⽗類的構(gòu)造⽅法,會存在⼀份多余的⽗類實例屬性
寄生組合式繼承
核心:結(jié)合借用構(gòu)造函數(shù)傳遞參數(shù)和寄生模式實現(xiàn)繼承
function Parent(name){ this.name = name || 'xt', this.arr = [1] } function Son(name,age){ Parent.call(this,name) // 核⼼ this.age = age } Parent.prototype.say = function() { console.log('hello'); } Son.prototype = Object.create(Parent.prototype) // 核心 通過創(chuàng)建中間對象,⼦類原型和⽗類原型,就會隔離開。 Son.prototype.constructor = Son let p1 = new Parent() let s1 = new Son("小紅",18) let s2 = new Son("小黑",19) console.log(p1.constructor); //[Function: Parent] console.log(s1.constructor); // [Function: Son] console.log(s1.say() === s2.say()); //true console.log(s1.name,s1.age); // 小紅 18 console.log(s2.name,s2.age); //小黑 19 s1.arr.push(2) console.log(s1.arr,s2.arr); // [ 1, 2 ] [ 1, 2 ]
寄生式組合繼承可以算是引用類型繼承的最佳繼承
總結(jié)
到此這篇關(guān)于JS繼承的文章就介紹到這了,更多相關(guān)JS繼承的理解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用于CSS代碼壓縮與格式化的javascript函數(shù)代碼
呵呵,發(fā)現(xiàn)只要幾行JS代碼就可實現(xiàn)css的壓縮與格式化,非常不錯。2009-12-12JavaScript es6中var、let以及const三者區(qū)別案例詳解
這篇文章主要介紹了JavaScript es6中var、let以及const三者區(qū)別案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08JavaScript限制在客戶區(qū)可見范圍的拖拽(解決scrollLeft和scrollTop的問題)(2)
這篇文章主要介紹了JavaScript限制在客戶區(qū)可見范圍的拖拽,解決scrollLeft和scrollTop的問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05javascript將DOM節(jié)點添加到文檔的方法實例分析
這篇文章主要介紹了javascript將DOM節(jié)點添加到文檔的方法,對比分析了javascript的兩種節(jié)點創(chuàng)建的方法,涉及javascript節(jié)點操作及運行時間計算的相關(guān)技巧,需要的朋友可以參考下2015-08-08javascript 用函數(shù)語句和表達式定義函數(shù)的區(qū)別詳解
本篇文章主要介紹了javascript 用函數(shù)語句和表達式定義函數(shù)的區(qū)別。需要的朋友可以過來參考下,希望對大家有所幫助2014-01-01