摘要:中的繼承概述原型鏈可以用來(lái)實(shí)現(xiàn)共享,構(gòu)造函數(shù)可以讓對(duì)象擁有自己的屬性,兩者結(jié)合的組合的組合繼承便是最常用的繼承方式。不易理解的地方的屬性在實(shí)例中而不在構(gòu)造函數(shù)中的屬性在中而不在構(gòu)造函數(shù)中。
1 前言
我試圖用簡(jiǎn)單、清晰、專業(yè)的方式講清楚js繼承這么一個(gè)有點(diǎn)復(fù)雜的問(wèn)題
2 繼承的精髓 2.1 為什么要繼承?因?yàn)樾枰獜?fù)用
2.2需要復(fù)用什么?該如何復(fù)用?通過(guò)復(fù)用我們可以實(shí)現(xiàn)共享。
從對(duì)象的角度來(lái)說(shuō),我們不想重復(fù)寫同一段邏輯,所以邏輯需要復(fù)用;但是我們不希望一個(gè)對(duì)象掌管的變量被其它對(duì)象修改。所以變量不能共享。也就是要共享函數(shù),不共享屬性。
3 js中的繼承 3.1 概述原型鏈可以用來(lái)實(shí)現(xiàn)共享,構(gòu)造函數(shù)可以讓對(duì)象擁有自己的屬性,兩者結(jié)合的組合的組合繼承便是最常用的繼承方式。
組合繼承中有一個(gè)弊端,通過(guò)簡(jiǎn)單的改進(jìn),寄生組合式繼承可以實(shí)現(xiàn)最有效的繼承。接下來(lái)將展開講解組合繼承和寄生組合式繼承。
3.2 預(yù)備知識(shí)如果已經(jīng)了解了這些知識(shí),可以直接跳過(guò)
function Person () { } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job="Software Engineer"; Person.prototype.sayName=function () { console.log(this.name); }; var person1=new Person(); person1.sayName();//Nicholas
構(gòu)造函數(shù)(Person)可以用來(lái)創(chuàng)建實(shí)例(person1),創(chuàng)建的實(shí)例和構(gòu)造函數(shù)共同指向一個(gè)原型(Person.prototype),原型的構(gòu)造器又指向了構(gòu)造函數(shù)。
如果沒(méi)有指定原型,則默認(rèn)的原型為Object.prototype。
new操作符具體干了什么呢?
創(chuàng)建一個(gè)空對(duì)象,并且 this 變量引用該對(duì)象,同時(shí)還繼承了該函數(shù)的原型。var obj = {};
屬性和方法被加入到 this 引用的對(duì)象中。obj.__proto__ = Base.prototype; (圖示中用[[Prorotype]]代表__proto__)
新創(chuàng)建的對(duì)象由 this 所引用,并且最后隱式的返回 this 。Base.call(obj);
屏蔽:
//...上面的代碼,此處省略 var person2=new Person(); person1.name="Mike"; person1.sayName();//Mike person2.sayName();//Nicholas
屬性值沿著原型鏈,遵循就近原則。就近的屬性值會(huì)屏蔽上層原型鏈的屬性值
動(dòng)態(tài)追加而非斷開:
誤區(qū):javaScript高級(jí)程序設(shè)計(jì)第三版 中指出了 修改原型時(shí) 這樣一種斷開情景
function Person () { } var friend=new Person(); Person.prototype={ constructor:Person, name:"Nicholas", age:29, job:"Software Engineer", sayName:function () { console.log(this.name); } } friend.sayName();//error
friend的原型丟失了,和它斷開了聯(lián)系。
其實(shí)現(xiàn)在已經(jīng)有所改進(jìn),運(yùn)行friend.sayName();,應(yīng)該輸出為:Nicholas,當(dāng)修改原型時(shí),語(yǔ)言的設(shè)計(jì)意圖是什么?如果你是語(yǔ)言的設(shè)計(jì)者到底應(yīng)該為何種輸出?
我認(rèn)為最好的效果是確保其穩(wěn)妥性的同時(shí),又不失靈活是最佳的,在這個(gè)例子中,創(chuàng)建完原型關(guān)系后又想追加原型中的屬性,我希望他能夠追加成功,因此,希望它輸出為:Nicholas。
但是,我不希望原型中的屬性隨意修改,先開始的時(shí)候我給他賦予了值,也定義了相應(yīng)的方法使用這個(gè)值,如果這個(gè)值在后期隨意修改的話,使用這個(gè)方法的時(shí)候會(huì)覺(jué)得不知所措。
所以我希望的涉及是原型屬性值可以追加但定義后值不能隨意修改,如下:
function Person () { } Person.prototype.name = "Greg"; Person.prototype.age = 24; Person.prototype.job="Doctor"; var friend=new Person(); Person.prototype={ constructor:Person, name:"Nicholas", age:29, job:"Software Engineer", sayName:function () { console.log(this.name); } } friend.sayName();//Greg
打印friend.__proto__:
Object {name: "Greg", age: 24, job: "Doctor"} age:24 job:"Doctor" name:"Greg" sayName:function()3.2.3 總結(jié)
橫向上,每個(gè)原型的屬性 在原型本身被修改時(shí) 只是動(dòng)態(tài)追加而不會(huì)修改原值;縱向上,原型鏈繼承遵循就近原則。
3.3 組合繼承讓一個(gè)構(gòu)造函數(shù)A的原型為另一個(gè)構(gòu)造函數(shù)B的實(shí)例,便形成了A繼承B的原型鏈。
function SuperType() { this.property=true; } SuperType.prototype.getSuperValue=function () { return this.property; }; function SubType() { this.subproperty=false; }; SubType.prototype=new SuperType(); SubType.prototype.getSubValue=function () { return this.subproperty; } var instance=new SubType();
不易理解的地方:subproperty的屬性在實(shí)例中而不在SubType構(gòu)造函數(shù)中;property的屬性在 SubType.prototype中而不在SuperType構(gòu)造函數(shù)中。
講解:subproperty和property都是實(shí)例屬性,在哪里創(chuàng)建了實(shí)例就出現(xiàn)在哪里,
優(yōu)勢(shì):函數(shù)共享
缺陷:原型鏈體現(xiàn)出了共享的特性,當(dāng)一個(gè)實(shí)例改變了其從原型那里繼承來(lái)的引用屬性值時(shí),其它繼承自這個(gè)原型屬性的值都將被改變。
function SuperType() { this.colors=["red","blue","green"]; } function SubType() { }; SubType.prototype=new SuperType(); var instance1=new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//["red", "blue", "green", "black"] var instance2=new SubType(); console.log(instance2.colors);//["red", "blue", "green", "black"]
function SuperType(name) { this.name=name; } function SubType() { SuperType.call(this,"Nicholas"); this.age=29; } var instance=new SubType(); console.log(instance.name+" "+instance.age);//Nicholas 29
構(gòu)造函數(shù)每個(gè)實(shí)例的屬性都借助構(gòu)造函數(shù)自己生成
優(yōu)勢(shì):每個(gè)實(shí)例屬性各自獨(dú)立
缺陷:無(wú)法共享函數(shù)
組合繼承結(jié)合了原型鏈繼承和構(gòu)造函數(shù)繼承的優(yōu)勢(shì):
function SuperType(name) { this.name=name; this.colors=["red","blue","green"] } SuperType.prototype.sayName=function () { console.log(this.name); } function SubType(name,age) { SuperType.call(this,name); this.age=age; } SubType.prototype=new SuperType(); SubType.prototype.sayAge=function () { console.log(this.age); } var instance1=new SubType("Nicholas",29); instance1.colors.push("black"); console.log(instance1.colors); instance1.sayName(); instance1.sayAge(); var instance2=new SubType("Greg",27); console.log(instance2.colors); instance2.sayName(); instance2.sayAge();3.4 寄生組合式繼承
組合繼承雖然實(shí)現(xiàn)了需求:共享函數(shù),但不共享屬性,可是它是有不足之處:我們?cè)讵?dú)立屬性時(shí)只是希望實(shí)例有各自的屬性就好了,不需要原型(SubType.prototype)中也存在屬性,這就多余了。
SubType.prototype存在屬性是因?yàn)樗鼘?duì)SuperType做了實(shí)例化繼承,我們將實(shí)例話繼承換成前拷貝繼承便可以解決問(wèn)題:
//將組合繼承中的實(shí)例化繼承: //SubType.prototype=new SuperType(); //改為淺拷貝繼承: function inheritPrototype(subType,superType){ var prototype=Object.create(superType.prototype);//創(chuàng)建對(duì)象 prototype.constructor=subType; subType.prototype=prototype; } inheritPrototype(SubType,SuperType);
Object.create()代碼說(shuō)明:
function Object.create(o){ function F() {}; F.prototype=o; return new F(); }參考
javascript高級(jí)程序設(shè)計(jì) 第三版
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/80065.html
摘要:在本節(jié)中,我們將看到一些最流行和最常用的庫(kù),用于機(jī)器學(xué)習(xí)和深度學(xué)習(xí)是用于數(shù)據(jù)挖掘,分析和機(jī)器學(xué)習(xí)的最流行的庫(kù)。愿碼提示網(wǎng)址是一個(gè)基于的框架,用于使用多個(gè)或進(jìn)行有效的機(jī)器學(xué)習(xí)和深度學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000018961827?w=999&h=562); 來(lái)源 | 愿碼(ChainDesk.CN)內(nèi)容編輯...
摘要:接下來(lái)本清單還列舉了對(duì)于接入過(guò)濾與防攻擊使用合適的方法并且對(duì)用戶輸入進(jìn)行有效校驗(yàn)避免關(guān)鍵資源外泄設(shè)置合理的響應(yīng)頭等等內(nèi)容。該論文的主要論點(diǎn)是,沒(méi)有任何一項(xiàng)技術(shù)或方法可以能讓軟件工程的生產(chǎn)力在十年內(nèi)提高十倍。 推薦 1. Styled-Components 實(shí)戰(zhàn) https://hackernoon.com/styled... Styled-Components 是由 Max Stoib...
摘要:接下來(lái)本清單還列舉了對(duì)于接入過(guò)濾與防攻擊使用合適的方法并且對(duì)用戶輸入進(jìn)行有效校驗(yàn)避免關(guān)鍵資源外泄設(shè)置合理的響應(yīng)頭等等內(nèi)容。該論文的主要論點(diǎn)是,沒(méi)有任何一項(xiàng)技術(shù)或方法可以能讓軟件工程的生產(chǎn)力在十年內(nèi)提高十倍。 推薦 1. Styled-Components 實(shí)戰(zhàn) https://hackernoon.com/styled... Styled-Components 是由 Max Stoib...
摘要:從零開始單排學(xué)設(shè)計(jì)模式的國(guó)服排位之旅,今天正式開啟目前段位定級(jí)賽這篇文章來(lái)總結(jié)下類圖,本來(lái)不打算講類圖的,因?yàn)槲以趯W(xué)習(xí)設(shè)計(jì)模式的時(shí)候,一遇到有關(guān)的就會(huì)自動(dòng)忽略,一看感覺(jué)就很復(fù)雜。關(guān)聯(lián)關(guān)系用實(shí)現(xiàn)箭頭來(lái)表示。 閱讀本文大概需要 3.5 分鐘。 本篇是設(shè)計(jì)模式系列的開篇,雖然之前也寫過(guò)相應(yīng)的文章,但是因?yàn)榉N種原因后來(lái)斷掉了,而且發(fā)現(xiàn)之前寫的內(nèi)容也很渣,不夠系統(tǒng)。 所以現(xiàn)在打算重寫,加上距離現(xiàn)...
閱讀 2793·2021-11-24 09:39
閱讀 2553·2021-11-23 09:51
閱讀 1838·2021-11-17 09:33
閱讀 1744·2021-10-22 09:54
閱讀 1878·2021-08-16 11:00
閱讀 3428·2019-08-30 15:53
閱讀 1737·2019-08-30 13:19
閱讀 2908·2019-08-30 12:49