js各种方法继承以及优缺点
一、原型鏈繼承
原型鏈繼承就是將父類的實例賦給子類的原型對象
function parent(name){this.name = 'jack'; } parent.prototype.getName = function(){console.log(this.name) } function child(){} child.prototype = new parent(); const child1 = new child() child1.getName();//jack console.log(child.name);//jack 復制代碼優(yōu)點: 可以直接繼承父類的屬性和方法,這里的屬性繼承是通過__proto__找到的,不是實例本身擁有的。
缺點: 1.不能向父類傳參; 2.引用屬性會被所有實例共享。
就像下面這種情況,屬性被實例共享導致引用類型易被修改:
function parent(){this.name = ['tom','jack'] } parent.prototype.getName = function(){console.log(this.name) } function child(){} child.prototype = new parent(); const child1 = new child(); const child2 = new child(); child1.name.push("jery") console.log(child1.name,child2.name)//['tom','jack','jery'] 復制代碼child的constructor指向parent,所以我們使用的時候應(yīng)該手動修改指向:
child.prototype.constructor = child;
二、構(gòu)造函數(shù)繼承
構(gòu)造函數(shù)繼承就是在子類調(diào)用父類來實現(xiàn)繼承
function parent(name){this.name = name; } function child(name){parent.call(this,name); } const child1 = new child('jack'); console.log(child1.name)//jack 復制代碼優(yōu)點:可以繼承父類的屬性(這里的屬性繼承是實例本身自己的),可以向父類傳參,引用類型不會被所有實例共享,constructor還是指向自己child。
缺點:不能繼承父類原型上的方法,方法都在構(gòu)造函數(shù)中定義,每次創(chuàng)建實例都會創(chuàng)建一遍方法。
function parent(name){this.name = name;this.arr = ['111'] } function child(name){parent.call(this,name); } const jack = new child('jack'); const tom = new child('tom') jack.arr.push('222'); console.log(jack.arr,tom.arr)//(2) ["111", "222"] ["111"] 復制代碼所以上面兩個繼承方式各有優(yōu)劣,一個能繼承父類的方法,但是屬性被實例共享,易修改,另一個方式雖然能很好的繼承父類的屬性(這里的屬性是自己的),但是父類原型上的方法被多次創(chuàng)建。于是看看下面這位:
三、組合繼承
如果結(jié)合原型繼承和構(gòu)造函數(shù)繼承,這樣就可以結(jié)合其優(yōu)點,摒棄其缺點了,這就是組合繼承
function parent(name){this.name = name;this.arr = ['111'] } parent.prototype.getName = function(){console.log(this.name) } function child(name){parent.call(this,name) } child.prototype = new parent(); const jack = new child('jack'); const tom = new child('tom'); jack.arr.push('222'); jack.getName();//jack console.log(jack.arr,tom.arr)//2) ["111", "222"] ["111"] 復制代碼優(yōu)點: 可以向父類傳參,可以繼承父類的屬性(子類會有從父類繼承的屬性,__proto__上基本屬性是undefined,引用屬性是有的,看下圖)和原型上的方法,引用屬性不會被共享:
缺點: 一個實例會實例化父類兩次,parent.call(this,name)調(diào)用一次,child.prototype = new parent()調(diào)用一次,constructor指向了parent。
三、原型繼承
function create(o){function Fun(){};Fun.prototype = o;return new Fun(); } 復制代碼原型繼承其實就是es5的object.create()的實現(xiàn)方式,請看下面的代碼:
const person = {name: 'name',arr: ['111','222'] } const p1 = create(person); const p2 = create(person); p1.name = 'p1'; p1.arr.push('aaa'); console.log(p1.name,p2.name);//p1,name console.log(p1.arr,p2.arr);//(3) ["111", "222", "aaa"] (3) ["111", "222", "aaa"] 復制代碼缺點:會共享引用屬性
修改p1.name的值,p2.name的值并未發(fā)生改變,并不是因為p1和p2有獨立的 name 值,而是 因為p1.name='p1',給person1添加了 name 值,并非修改了原型上的name,值。p1,p2的constructor屬性是指向object的,p1.name是在父類原型上找到的,p2.name=‘name’,繼承的屬性在__proto__。
四、寄生式繼承
創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)在內(nèi)部以某種形式來做增強對象,最后返回對象。
function createObj (o) {var clone = object.create(o);clone.sayName = function () {console.log('hi');}return clone; } 復制代碼缺點:跟構(gòu)造函數(shù)模式一樣,每次創(chuàng)建對象都會創(chuàng)建一遍方法。
五、寄生組合式繼承
繼承終極大boss!!寄生組合式繼承,結(jié)合了以上的優(yōu)點,來看下代碼 組合繼承的缺點就是會調(diào)用兩次父類,如何避免調(diào)用兩次呢?能不能直接讓子類的prototype訪問到父類的prototype?當然可以!!看下面的代碼
function parent(name){this.name = name;this.arr = ['111'] } parent.prototype.getName = function(){console.log(this.name) } function child(name){parent.call(this,name) } //注意!!核心代碼(解決調(diào)用兩次父類) function Fun(){} Fun.prototype = parent.prototype; child.prototype = new Fun();const c1 = new child('c1'); const c2 = new child('c2'); c1.arr.push('ccc'); c1.name = 'name'; c1.getName();//name c2.getName();//c2 console.log(c1,c2);//child {name: "name", arr: Array(2)} child {name: "c2", arr: Array(1)} 復制代碼 優(yōu)點:可以繼承父類的屬性和原型上的方法,實例間不會共享引用屬性,基本屬性也可以繼承變成自己的屬性,不會執(zhí)行兩遍父類。缺點: 子類的constructor指向指向了父類,應(yīng)該修復一下,可以改寫如下 可以改寫上面的關(guān)鍵步驟:
function create(o){function F(){}F.prototype = o;return new F(); } function prototype(child,parent){const p = create(parent.prototype);p.constructor = child;child.prototype = p; } 復制代碼轉(zhuǎn)載于:https://juejin.im/post/5bbca0c6f265da0aa35946b3
總結(jié)
以上是生活随笔為你收集整理的js各种方法继承以及优缺点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下切换用户出现su: Auth
- 下一篇: jquery4