摘要:這又是什么呢這個(gè)相對(duì)之前的比較復(fù)雜,但是高效的一點(diǎn)是只調(diào)用一次被繼承者構(gòu)造函數(shù)原理就是通過(guò)寄生方式創(chuàng)建一個(gè)被繼承者的副本,副本和被繼承者共用一個(gè)這樣就解決了之前的問(wèn)題返回的一個(gè)副本設(shè)置指向因?yàn)樾赂北镜脑蛯?duì)象被重寫(xiě)副本作為的原型對(duì)象
前言
我們學(xué)JAVA的時(shí)候說(shuō)到繼承就是一個(gè)extends ClassName的事情,但是在JS的世界里繼承和我們?cè)贘AVA所認(rèn)識(shí)的繼承實(shí)現(xiàn)方法又有一些不同,你們真的了解JS的繼承嗎?就當(dāng)你們很了解了,畢竟是基礎(chǔ)知識(shí),我就簡(jiǎn)單說(shuō)說(shuō)
原型鏈繼承簡(jiǎn)言之就是把被繼承的對(duì)象賦值給繼承者的原型對(duì)象
function Super() { this.name = "mirok"; } Super.prototype.showName = function () { console.log(this.name); } function Sub() { this.name = "july"; } Sub.prototype = new Super(); const obj = new Sub(); obj.showName(); //輸出july
原型實(shí)現(xiàn)繼承雖然可以,但是也有相應(yīng)的弊端,例如new Super()構(gòu)建多個(gè)實(shí)例,繼承里面的方法被其中一個(gè)實(shí)例重寫(xiě),就會(huì)影響其他實(shí)例,也就是說(shuō)原型里的是所有實(shí)例所共享的,這是我們不愿看到的,因此就有以下的方法。
借用構(gòu)造函數(shù)簡(jiǎn)言之就是在繼承者的構(gòu)造函數(shù)中去調(diào)用被繼承者的構(gòu)造函數(shù)(即使用apply()/call()實(shí)現(xiàn))
function Super() { this.supername = "mirok"; } function Sub() { Super.call(this) this.name = "july"; } Sub.prototype = new Super(); const obj = new Sub(); obj.name; //july obj.supername; //mirok
這種方式實(shí)現(xiàn)的繼承相對(duì)于之前的來(lái)說(shuō)不僅解決了之前的問(wèn)題還能向被繼承者傳參數(shù),但是也有一定的弊端,即容易覆蓋本身的屬性,解決方法就是在調(diào)用被繼承者的構(gòu)造函數(shù)再對(duì)自己添加屬性,也就是說(shuō)上面的Super.call要在this.name定義屬性之前。另一個(gè)弊端就是繼承的是無(wú)法共享的
組合繼承這個(gè)就是組合前面的原型鏈繼承和借用構(gòu)造函數(shù)繼承兩者之長(zhǎng),也就是說(shuō)既能在繼承后的實(shí)例都有一份屬性又能共用
function Super() { this.name = "mirok"; } Super.prototype.showName = function () { console.log(this.name); } function Sub1() { Super.call(this); this.name = "july"; } function Sub2() { Super.call(this); this.name = "deny"; } Sub1.prototype = new Super(); Sub2.prototype = new Super(); const obj1 = new Sub1(); const obj2 = new Sub2(); obj1.showName(); // july obj2.showName(); // deny原型式繼承
這個(gè)比較特殊一點(diǎn),就是在一個(gè)函數(shù)里去做原型鏈繼承的事情
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); }
ES5規(guī)范了這類(lèi)寫(xiě)法,就是Object.create(),但是弊端和第一種類(lèi)似,因?yàn)椴皇俏覀兝硐氲睦^承這里就不詳細(xì)介紹
寄生式繼承這個(gè)也比較特殊,就是把繼承的事情放在一個(gè)函數(shù)里去做,再把對(duì)象返回
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); } function factory() { const person = {name:"mirok", age: 22}; const obj = object(person); obj.show = function() {console.log(this.name)} return obj; } factory().show(); //"mirok"
至于弊端可見(jiàn)而知,不能實(shí)現(xiàn)共享
寄生組合式繼承組合繼承有個(gè)弊端就是會(huì)調(diào)用兩次被繼承者的構(gòu)造函數(shù),解決方法就是使用寄生組合式繼承。這又是什么呢?這個(gè)相對(duì)之前的比較復(fù)雜,但是高效的一點(diǎn)是只調(diào)用一次被繼承者構(gòu)造函數(shù),原理就是通過(guò)寄生方式創(chuàng)建一個(gè)被繼承者的副本,副本和被繼承者共用一個(gè)prototype,這樣就解決了之前的問(wèn)題
function object(obj) { function fun() {}; fun.prototype = obj; return new fun(); } function factory(Sub, Super) { var proto = object(Super.prototype); //返回Super的一個(gè)副本 proto.constructer = Sub; //設(shè)置constructor指向, 因?yàn)樾赂北镜脑蛯?duì)象被重寫(xiě) Sub.prototype = proto; //副本作為sub的原型對(duì)象 } function Super () { this.name = "july"; } Super.prototype.show = function () { console.log(this.name); } function Sub1 () { Super.call(this); this.name = "mirok" } function Sub2 () { Super.call(this); this.name = "deny" } factory(Sub1, Super); factory(Sub2, Super); var obj1 = new Sub1(); var obj2 = new Sub2(); obj1.show(); // mirok obj2.show(); // deny
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96757.html
摘要:前言還記得當(dāng)初用語(yǔ)言寫(xiě)各種數(shù)據(jù)結(jié)構(gòu)的苦逼時(shí)代嘛,但是用來(lái)實(shí)現(xiàn)棧和隊(duì)列是如此的簡(jiǎn)單啊,但是你們真的了解用模擬棧和隊(duì)列,就當(dāng)你們真的很了解了,畢竟是基礎(chǔ)知識(shí),我就寫(xiě)幾個(gè)案例,不喜勿噴棧棧方法棧就是先進(jìn)后出,就是如此便捷就可以簡(jiǎn)單實(shí)現(xiàn)棧隊(duì)列隊(duì)列是 前言: 還記得當(dāng)初用C語(yǔ)言寫(xiě)各種數(shù)據(jù)結(jié)構(gòu)的苦逼時(shí)代嘛,但是用JS來(lái)實(shí)現(xiàn)棧和隊(duì)列是如此的簡(jiǎn)單啊,但是你們真的了解用js模擬棧和隊(duì)列,就當(dāng)你們真的很了...
摘要:我們知道創(chuàng)建了一個(gè)函數(shù)就帶了一個(gè)屬性,創(chuàng)建一個(gè)實(shí)例就帶著一個(gè)指針,這個(gè)指針是實(shí)例和構(gòu)造函數(shù)的原型對(duì)象間的聯(lián)系,這個(gè)指針在腳本中是不可見(jiàn)的,也就是你不能訪問(wèn)的,但是在和中,提供了來(lái)支持訪問(wèn),這么一說(shuō),相信大家應(yīng)該能明白吧 前言 一般我們看到prototype就會(huì)下意識(shí)的說(shuō)這不就是原型對(duì)象嘛?但是你們真的了解prototype嘛?就當(dāng)你們很了解了,畢竟是基礎(chǔ)知識(shí),我就簡(jiǎn)單說(shuō)說(shuō) 正文 先說(shuō)說(shuō)...
摘要:使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,用借用構(gòu)造函數(shù)模式實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。 我們之前介紹了javascript面向?qū)ο蟮姆庋b的相關(guān)內(nèi)容,還介紹了js的call方法,今天開(kāi)始討論js的繼承這篇文章參考了《javascript高級(jí)程序設(shè)計(jì)》(第三版),但內(nèi)容不局限于,網(wǎng)上很多關(guān)于js繼承的相關(guān)內(nèi)容都是來(lái)自于這本書(shū),有興趣的同學(xué)可以翻閱查看 原型鏈繼承 我們先通過(guò)一個(gè)栗子,了解一下原型鏈...
摘要:前言函數(shù)傳參我們天天都在用,但是你們真的了解嘛就當(dāng)你們很了解了,畢竟是一些基礎(chǔ)的東西,我就寫(xiě)幾個(gè)例子,不喜勿噴。 前言 函數(shù)傳參我們天天都在用,但是你們真的了解嘛?就當(dāng)你們很了解了,畢竟是一些基礎(chǔ)的東西,我就寫(xiě)幾個(gè)例子,不喜勿噴。 例子 demo1: var obj = {name: mirok} function demo1(obj) { obj.name = july }...
摘要:面試官要不你來(lái)手寫(xiě)下單例模式唄候選者單例模式一般會(huì)有好幾種寫(xiě)法候選者餓漢式簡(jiǎn)單懶漢式在方法聲明時(shí)加鎖雙重檢驗(yàn)加鎖進(jìn)階懶漢式靜態(tài)內(nèi)部類(lèi)優(yōu)雅懶漢式枚舉候選者所謂餓漢式指的就是還沒(méi)被用到,就直接初始化了對(duì)象。面試官:我看你的簡(jiǎn)歷寫(xiě)著熟悉常見(jiàn)的設(shè)計(jì)模式,要不你來(lái)簡(jiǎn)單聊聊你熟悉哪幾個(gè)吧?候選者:常見(jiàn)的工廠模式、代理模式、模板方法模式、責(zé)任鏈模式、單例模式、包裝設(shè)計(jì)模式、策略模式等都是有所了解的候選者:...
閱讀 1854·2021-08-19 11:12
閱讀 1430·2021-07-25 21:37
閱讀 992·2019-08-30 14:07
閱讀 1271·2019-08-30 13:12
閱讀 655·2019-08-30 11:00
閱讀 3534·2019-08-29 16:28
閱讀 996·2019-08-29 15:33
閱讀 2978·2019-08-26 13:40