摘要:組合方式繼承終極版工商建設(shè)開(kāi)心能分清是孩子還是父輩二狗的構(gòu)造函數(shù)已指向圖示關(guān)鍵代碼創(chuàng)建對(duì)象的方法就是用原型鏈來(lái)連接的。也讓二狗有了確定的歸屬。
一、繼承原理
原型鏈
不知道什么是原型鏈?
來(lái)讀幾個(gè)關(guān)鍵詞:
哥歐 構(gòu) 構(gòu)造函數(shù) 構(gòu)造函數(shù) 構(gòu)造函數(shù) 實(shí)例 實(shí)例 實(shí)例 原型對(duì)象 原型對(duì)象 原型對(duì)象 prototype prototype prototype __proto__ __proto__ __proto__ constructor constructor constructor instanceof instanceof instanceof實(shí)現(xiàn)instanceof
function newInstanceof (left, right) { let leftProto = left.__proto__; let rightPrototype = right.prototype while(true) { if(leftProto === rightPrototype) { return true; } else if (leftProto === null) { return false; } else { leftProto = leftProto.__proto__ } } }二、繼承方法 1、構(gòu)造函數(shù)
function FatherA() { this.money = 100000; } function ChildA() { FatherA.call(this); this.soliloquy = "開(kāi)心"; } var childAng = new ChildA(); FatherA.prototype.makeMoneyWay = function () { console.log("next lottery number is ……"); }
假設(shè)某地有個(gè)習(xí)俗,F(xiàn)atherA會(huì)給ChildA準(zhǔn)備10萬(wàn)教育基金,
構(gòu)造函數(shù)繼承可以完美的讓孩子獲取到準(zhǔn)備好的教育基金。
然而這個(gè)時(shí)候FatherA新領(lǐng)悟到了一串神秘代碼,childAng卻用不了
childAng.makeMoneyWay(); // 會(huì)報(bào)錯(cuò)
這樣的繼承感覺(jué)不是親身的。
2、原型鏈繼承function FatherB() { this.money = 100000; this.card = ["工商", "建設(shè)"]; } function ChildB() { this.soliloquy = "開(kāi)心"; } ChildB.prototype = new FatherB() var childBobo = new ChildB(); var childBigShuan = new ChildB(); FatherB.prototype.makeMoneyWay = function () { console.log("next lottery number is ……"); } childBobo.card.push("招商"); // 引用類(lèi)型受影響 childBobo.money += 1000; // 值類(lèi)型在此不受影響
原型鏈繼承解決了構(gòu)造函數(shù)的問(wèn)題,F(xiàn)atherB上新的技能,ChildB的實(shí)例也能很好的使用。
圖示:
然而一個(gè)新問(wèn)題就是,當(dāng)實(shí)例有多個(gè)例如childBobo(波波)和childBigSuan(大栓)。
波波這個(gè)時(shí)候新辦了一張銀行卡,結(jié)果大栓立馬能用,這樣讓波波覺(jué)得很沒(méi)有隱私,哦不,是很不公平,憑啥你刷我的卡。
function FatherC() { this.money = 100000; this.card = ["工商", "建設(shè)"]; } function ChildC() { FatherC.call(this); this.soliloquy = "開(kāi)心"; } ChildC.prototype = new FatherC() var childCuifa = new ChildC(); var childChizi = new ChildC(); FatherC.prototype.makeMoneyWay = function () { console.log("next lottery number is ……"); } childCuifa.card.push("招商"); childCuifa.money += 1000;
出了問(wèn)題總要解決,這時(shí)候出現(xiàn)了由構(gòu)造函數(shù)和原型鏈的組合繼承,這樣既讓ChildC實(shí)例的數(shù)據(jù)相互獨(dú)立,也讓ChildC能獲取到FatherC的新技能。
社會(huì)問(wèn)題是解決了。新的問(wèn)題就是性能問(wèn)題,這類(lèi)繼承會(huì)調(diào)用FatherC兩次。顯然用的越多,消耗的資源越多。(雖然現(xiàn)在硬件很發(fā)達(dá),但是1個(gè)人睡100平米的床終究還是不方面,起夜還沒(méi)下床呢就尿了)
function FatherD() { this.money = 100000; this.card = ["工商", "建設(shè)"]; } function ChildD() { FatherD.call(this); this.soliloquy = "開(kāi)心"; } ChildD.prototype = FatherD.prototype var childDazhu = new ChildD(); var childDabing = new ChildD(); console.log("分不清是孩子還是父輩", childDazhu instanceof ChildD, childDazhu instanceof FatherD); console.log("大柱的構(gòu)造函數(shù)指向的是ParentD", childDazhu.constructor);
上一個(gè)組合繼承中
ChildC.prototype = new FatherC()
這行代碼主要是為了讓ChildC.prototype與new FatherC()的__proto__在一條原型鏈上。
所以換個(gè)思路,new FatherC()的__proto__也就是FatherC.protorype。
圖示:
替換后,既不會(huì)再執(zhí)行FatherC,也讓原型鏈合并到了一起。
這個(gè)方案的隱藏問(wèn)題就是,childDazhu(大柱)這個(gè)實(shí)例,會(huì)讓人不知道是孩子還是爸爸。
function FatherE() { this.money = 100000; this.card = ["工商", "建設(shè)"]; } function ChildE() { FatherE.call(this); this.soliloquy = "開(kāi)心"; } ChildE.prototype = Object.create(FatherE.prototype); ChildE.prototype.constructor = ChildE; var childErgo = new ChildE(); var childErwa = new ChildE(); var fatherErjun = new FatherE(); console.log("能分清是孩子還是父輩", childErgo instanceof ChildE, childErgo instanceof FatherE); console.log("二狗的構(gòu)造函數(shù)已指向childE", childErgo.constructor);
圖示:
關(guān)鍵代碼
Object.create
Object.create創(chuàng)建對(duì)象的方法就是用原型鏈來(lái)連接的。
Object.create()方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的__proto__。
參考自:
https://developer.mozilla.org...
var a = {name:"a"};
var b = Object.create(a);
b.__proto__ === a; // true
這樣ChildE與FatherE.prototype就在一條鏈上面了,并且數(shù)據(jù)也進(jìn)行了隔離,此時(shí)修改ChildE原型對(duì)象的構(gòu)造函數(shù)指向,不會(huì)影響到FatherE的原型對(duì)象。
也讓childErgo(二狗)有了確定的歸屬。
幸福的結(jié)局??!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95427.html
摘要:繼承方式一混入繼承繼承方式二原型繼承創(chuàng)建構(gòu)造函數(shù),并且將對(duì)象的地址賦值給構(gòu)造函數(shù)的原型實(shí)現(xiàn)繼承恢復(fù)三角關(guān)系實(shí)例化的所有對(duì)象都擁有對(duì)象的屬性和方法繼承方式三混入加原型繼承方式四實(shí)現(xiàn)過(guò)程了一個(gè)新的對(duì)象,把傳入作為參數(shù)的那個(gè)對(duì)象設(shè)置給新創(chuàng)建的這個(gè) 繼承方式一:混入繼承 use strict; //object:A let Oa= { money: many money, r...
摘要:老明調(diào)用了從原型中繼承來(lái)的方法繼承到了當(dāng)前對(duì)象的原型中調(diào)用了從原型中擴(kuò)展來(lái)的方法構(gòu)造繼承基本思想借用構(gòu)造函數(shù)的基本思想就是利用或者把父類(lèi)中通過(guò)指定的屬性和方法復(fù)制借用到子類(lèi)創(chuàng)建的實(shí)例中。 1、原型鏈繼承 核心: 將父類(lèi)的實(shí)例作為子類(lèi)的原型 缺點(diǎn): 父類(lèi)新增原型方法/原型屬性,子類(lèi)都能訪問(wèn)到,父類(lèi)一變其它的都變了 function Person (name) { ...
摘要:原型鏈繼承核心代碼核心代碼優(yōu)點(diǎn)簡(jiǎn)單容易實(shí)現(xiàn)缺點(diǎn)多拷貝了一份的屬性過(guò)來(lái)并且的方法每生成一個(gè)新的就要再重新拷貝一份造成了不必要的浪費(fèi)構(gòu)造函數(shù)繼承優(yōu)點(diǎn)簡(jiǎn)單容易實(shí)現(xiàn)可以同時(shí)繼承多個(gè)父對(duì)象三姓家奴缺點(diǎn)只能繼承定義在父元素上的屬性或方法而對(duì)于父元素原型 //1.原型鏈繼承 var supClass = function(name, sex) { ...
摘要:實(shí)現(xiàn)繼承的方法借用構(gòu)造函數(shù)解決原型中包含引用類(lèi)型所帶來(lái)的問(wèn)題的過(guò)程中,使用借用構(gòu)造函數(shù)偽造對(duì)象或經(jīng)典繼承來(lái)實(shí)現(xiàn)繼承。 繼承 在ECMAScript中繼承主要是依靠原型鏈來(lái)實(shí)現(xiàn)的。 實(shí)現(xiàn)繼承的方法 利用原型讓一個(gè)引用類(lèi)型繼承另一個(gè)引用類(lèi)型的屬性和方法 什么是原型鏈 先要了解構(gòu)造函數(shù)、原型、和實(shí)例的關(guān)系: 每一個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象,原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針,實(shí)例都包含...
摘要:原型鏈和構(gòu)造函數(shù)是一種面向?qū)ο蟮恼Z(yǔ)言,并且可以進(jìn)行原型繼承。來(lái)了極大的支持了工程化,它的標(biāo)準(zhǔn)讓瀏覽器內(nèi)部實(shí)現(xiàn)類(lèi)和類(lèi)的繼承構(gòu)造函數(shù)構(gòu)造函數(shù)調(diào)用父類(lèi)構(gòu)造函數(shù)現(xiàn)在瀏覽器對(duì)其支持程度還不高。 原型鏈 原型鏈比作用域鏈要好理解的多。 JavaScript中的每個(gè)對(duì)象,都有一個(gè)內(nèi)置的_proto_屬性。這個(gè)屬性是編程不可見(jiàn)的(雖然ES6標(biāo)準(zhǔn)中開(kāi)放了這個(gè)屬性,然而瀏覽器對(duì)這個(gè)屬性的可見(jiàn)性的支持不同)...
閱讀 2967·2021-10-14 09:43
閱讀 2915·2021-10-14 09:42
閱讀 4707·2021-09-22 15:56
閱讀 2387·2019-08-30 10:49
閱讀 1610·2019-08-26 13:34
閱讀 2401·2019-08-26 10:35
閱讀 627·2019-08-23 17:57
閱讀 2050·2019-08-23 17:15