日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

JavaScript六種繼承方式

瀏覽:34日期:2023-11-13 14:58:36

繼承是面向?qū)ο缶幊讨杏忠环浅V匾母拍睿琂avaScript支持實(shí)現(xiàn)繼承,不支持接口繼承,實(shí)現(xiàn)繼承主要依靠原型鏈來實(shí)現(xiàn)的

原型鏈

首先得要明白什么是原型鏈,在 一篇文章看懂 proto 和prototype的關(guān)系及區(qū)別 中講得非常詳細(xì)

原型鏈繼承基本思想就是讓一個原型對象指向另一個類型的實(shí)例

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()console.log(instance.getSuperValue()) // true

代碼定義了兩個類型SuperType和SubType,每個類型分別有一個屬性和一個方法,SubType繼承了SuperType,而繼承是通過創(chuàng)建SuperType的實(shí)例,并將該實(shí)例賦給SubType.prototype實(shí)現(xiàn)的

實(shí)現(xiàn)的本質(zhì)是重寫原型對象,代之以一個新類型的實(shí)例,那么存在SuperType的實(shí)例中的所有屬性和方法,現(xiàn)在也存在于SubType.prototype中了

我們知道,在創(chuàng)建一個實(shí)例的時候,實(shí)例對象中會有一個內(nèi)部指針指向創(chuàng)建它的原型,進(jìn)行關(guān)聯(lián)起來,在這里代碼 SubType.prototype = new SuperType() ,也會在SubType.prototype創(chuàng)建一個內(nèi)部指針,將SubType.prototype與SuperType關(guān)聯(lián)起來

所以instance指向SubType的原型,SubType的原型又指向SuperType的原型,繼而在instance在調(diào)用getSuperValue()方法的時候,會順著這條鏈一直往上找

添加方法

在給SubType原型添加方法的時候,如果,父類上也有同樣的名字,SubType將會覆蓋這個方法,達(dá)到重新的目的。 但是這個方法依然存在于父類中

記住不能以字面量的形式添加,因?yàn)椋厦嬲f過通過實(shí)例繼承本質(zhì)上就是重寫,再使用字面量形式,又是一次重寫了,但這次重寫沒有跟父類有任何關(guān)聯(lián),所以就會導(dǎo)致原型鏈截?cái)?/p>

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()console.log(instance.getSuperValue()) // error

問題

單純的使用原型鏈繼承,主要問題來自包含引用類型值的原型。

function SuperType(){ this.colors = [’red’, ’blue’, ’green’]}function SubType(){}SubType.prototype = new SuperType()var instance1 = new SubType()var instance2 = new SubType()instance1.colors.push(’black’)console.log(instance1.colors) // ['red', 'blue', 'green', 'black']console.log(instance2.colors) // ['red', 'blue', 'green', 'black']

在SuperType構(gòu)造函數(shù)定義了一個colors屬性,當(dāng)SubType通過原型鏈繼承后,這個屬性就會出現(xiàn)SubType.prototype中,就跟專門創(chuàng)建了SubType.prototype.colors一樣,所以會導(dǎo)致SubType的所有實(shí)例都會共享這個屬性,所以instance1修改colors這個引用類型值,也會反映到instance2中

借用構(gòu)造函數(shù)

此方法為了解決原型中包含引用類型值所帶來的問題

這種方法的思想就是在子類構(gòu)造函數(shù)的內(nèi)部調(diào)用父類構(gòu)造函數(shù),可以借助apply()和call()方法來改變對象的執(zhí)行上下文

function SuperType(){ this.colors = [’red’, ’blue’, ’green’]}function SubType(){ // 繼承SuperType SuperType.call(this)}var instance1 = new SubType()var instance2 = new SubType()instance1.colors.push(’black’)console.log(instance1.colors) // ['red', 'blue', 'green', 'black']console.log(instance2.colors) // ['red', 'blue', 'green']

在新建SubType實(shí)例是調(diào)用了SuperType構(gòu)造函數(shù),這樣以來,就會在新SubType對象上執(zhí)行SuperType函數(shù)中定義的所有對象初始化代碼

結(jié)果,SubType的每個實(shí)例就會具有自己的colors屬性的副本了

傳遞參數(shù)

借助構(gòu)造函數(shù)還有一個優(yōu)勢就是可以傳遞參數(shù)

function SuperType(name){ this.name = name}function SubType(){ // 繼承SuperType SuperType.call(this, ’Jiang’) this.job = ’student’}var instance = new SubType()console.log(instance.name) // Jiangconsole.log(instance.job) // student

問題

如果僅僅借助構(gòu)造函數(shù),方法都在構(gòu)造函數(shù)中定義,因此函數(shù)無法達(dá)到復(fù)用

組合繼承(原型鏈+構(gòu)造函數(shù))

組合繼承是將原型鏈繼承和構(gòu)造函數(shù)結(jié)合起來,從而發(fā)揮二者之長的一種模式

思路就是使用原型鏈實(shí)現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對實(shí)例屬性的繼承

這樣,既通過在原型上定義方法實(shí)現(xiàn)了函數(shù)復(fù)用,又能夠保證每個實(shí)例都有它自己的屬性

function SuperType(name){ this.name = name this.colors = [’red’, ’blue’, ’green’]}SuperType.prototype.sayName = function(){ console.log(this.name)}function SubType(name, job){ // 繼承屬性 SuperType.call(this, name) this.job = job}// 繼承方法SubType.prototype = new SuperType()SubType.prototype.constructor = SuperTypeSubType.prototype.sayJob = function(){ console.log(this.job)}var instance1 = new SubType(’Jiang’, ’student’)instance1.colors.push(’black’)console.log(instance1.colors) //['red', 'blue', 'green', 'black']instance1.sayName() // ’Jiang’instance1.sayJob() // ’student’var instance2 = new SubType(’J’, ’doctor’)console.log(instance2.colors) // //['red', 'blue', 'green']instance2.sayName() // ’J’instance2.sayJob() // ’doctor’

這種模式避免了原型鏈和構(gòu)造函數(shù)繼承的缺陷,融合了他們的優(yōu)點(diǎn),是最常用的一種繼承模式

原型式繼承

借助原型可以基于已有的對象創(chuàng)建新對象,同時還不必因此創(chuàng)建自定義類型

function object(o){ function F(){} F.prototype = o return new F()}

在object函數(shù)內(nèi)部,先創(chuàng)建一個臨時性的構(gòu)造函數(shù),然后將傳入的對象作為這個構(gòu)造函數(shù)的原型,最后返回這個臨時類型的一個新實(shí)例

本質(zhì)上來說,object對傳入其中的對象執(zhí)行了一次淺復(fù)制

var person = { name: ’Jiang’, friends: [’Shelby’, ’Court’]}var anotherPerson = object(person)console.log(anotherPerson.friends) // [’Shelby’, ’Court’]

這種模式要去你必須有一個對象作為另一個對象的基礎(chǔ)

在這個例子中,person作為另一個對象的基礎(chǔ),把person傳入object中,該函數(shù)就會返回一個新的對象

這個新對象將person作為原型,所以它的原型中就包含一個基本類型和一個引用類型

所以意味著如果還有另外一個對象關(guān)聯(lián)了person,anotherPerson修改數(shù)組friends的時候,也會體現(xiàn)在這個對象中

Object.create()方法

ES5通過Object.create()方法規(guī)范了原型式繼承,可以接受兩個參數(shù),一個是用作新對象原型的對象和一個可選的為新對象定義額外屬性的對象,行為相同,基本用法和上面的object一樣,除了object不能接受第二個參數(shù)以外

var person = { name: ’Jiang’, friends: [’Shelby’, ’Court’]}var anotherPerson = Object.create(person)console.log(anotherPerson.friends) // [’Shelby’, ’Court’] 寄生式繼承

寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個僅用于封裝繼承過程的函數(shù)

function createAnother(o){ var clone = Object.create(o) // 創(chuàng)建一個新對象 clone.sayHi = function(){ // 添加方法 console.log(’hi’) } return clone // 返回這個對象}var person = { name: ’Jiang’}var anotherPeson = createAnother(person)anotherPeson.sayHi()

基于person返回了一個新對象anotherPeson,新對象不僅擁有了person的屬性和方法,還有自己的sayHi方法

在主要考慮對象而不是自定義類型和構(gòu)造函數(shù)的情況下,這是一個有用的模式

寄生組合式繼承

在前面說的組合模式(原型鏈+構(gòu)造函數(shù))中,繼承的時候需要調(diào)用兩次父類構(gòu)造函數(shù)

父類

function SuperType(name){ this.name = name this.colors = [’red’, ’blue’, ’green’]}

第一次在子類構(gòu)造函數(shù)中

function SubType(name, job){ // 繼承屬性 SuperType.call(this, name) this.job = job}

第二次將子類的原型指向父類的實(shí)例

// 繼承方法SubType.prototype = new SuperType()

當(dāng)使用 var instance = new SubType() 的時候,會產(chǎn)生兩組name和color屬性,一組在SubType實(shí)例上,一組在SubType原型上,只不過實(shí)例上的屏蔽了原型上的

使用寄生式組合模式,可以規(guī)避這個問題

這種模式通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法

基本思路:不必為了指定子類型的原型而調(diào)用父類的構(gòu)造函數(shù),我們需要的無非就是父類原型的一個副本

本質(zhì)上就是使用寄生式繼承來繼承父類的原型,在將結(jié)果指定給子類型的原型

function inheritPrototype(subType, superType){ var prototype = Object.create(superType.prototype) prototype.constructor = subType subType.prototype = prototype}

該函數(shù)實(shí)現(xiàn)了寄生組合繼承的最簡單形式

這個函數(shù)接受兩個參數(shù),一個子類,一個父類

第一步創(chuàng)建父類原型的副本,第二步將創(chuàng)建的副本添加constructor屬性,第三部將子類的原型指向這個副本

function SuperType(name){ this.name = name this.colors = [’red’, ’blue’, ’green’]}SuperType.prototype.sayName = function(){ console.log(this.name)}function SubType(name, job){ // 繼承屬性 SuperType.call(this, name) this.job = job}// 繼承inheritPrototype(SubType, SuperType)var instance = new SubType(’Jiang’, ’student’)instance.sayName()

補(bǔ)充:直接使用Object.create來實(shí)現(xiàn),其實(shí)就是將上面封裝的函數(shù)拆開,這樣演示可以更容易理解

function SuperType(name){ this.name = name this.colors = [’red’, ’blue’, ’green’]}SuperType.prototype.sayName = function(){ console.log(this.name)}function SubType(name, job){ // 繼承屬性 SuperType.call(this, name) this.job = job}// 繼承SubType.prototype = Object.create(SuperType.prototype)// 修復(fù)constructorSubType.prototype.constructor = SubTypevar instance = new SubType(’Jiang’, ’student’)instance.sayName()

ES6新增了一個方法, Object.setPrototypeOf ,可以直接創(chuàng)建關(guān)聯(lián),而且不用手動添加constructor屬性

// 繼承Object.setPrototypeOf(SubType.prototype, SuperType.prototype)console.log(SubType.prototype.constructor === SubType) // true

來自:https://xxxgitone.github.io/2017/06/12/JavaScript六種繼承方式/

標(biāo)簽: JavaScript
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
99riav国产精品| 国产精品麻豆成人av电影艾秋| 激情综合自拍| 国产福利资源一区| 天堂va欧美ⅴa亚洲va一国产| 久久精品免费一区二区三区| 欧美在线亚洲| 国产成人久久精品麻豆二区| 亚洲免费福利一区| 激情欧美一区二区三区| 日韩.com| 欧美黄页在线免费观看| 亚州av一区| 日韩精品一区二区三区免费观看| 国产精品99精品一区二区三区∴| 久久亚洲影院| 亚洲欧美一级| 日韩电影免费在线观看| а√天堂8资源中文在线| 欧美激情福利| 国产aⅴ精品一区二区四区| 久久gogo国模啪啪裸体| 奇米狠狠一区二区三区| 日本vs亚洲vs韩国一区三区二区| 亚洲精品系列| 国产毛片久久| 红桃视频亚洲| 六月天综合网| 欧美一级一区| 一区免费视频| 日韩伦理福利| 精品国产午夜| 麻豆91小视频| 国产美女视频一区二区| 石原莉奈在线亚洲三区| 老司机久久99久久精品播放免费| 中文国产一区| 天使萌一区二区三区免费观看| 午夜亚洲精品| 美女av一区| 色婷婷综合网| 欧美男人天堂| 99精品在线免费在线观看| 久久久久中文| 国产精品老牛| 日本不卡一二三区黄网| 欧美性www| 精品国产亚洲一区二区三区在线 | 国产精品va| 狠狠久久伊人| 五月精品视频| 99国产精品私拍| 日韩欧美美女在线观看| 国产日产一区| 成人在线免费观看网站| 视频一区在线播放| 老司机精品久久| 久久国内精品| 日韩三区免费| 中文字幕日本一区| 精品国产午夜肉伦伦影院| 久久婷婷丁香| 蜜臀久久99精品久久久久宅男| 91九色综合| 欧美羞羞视频| 99国产精品久久久久久久| 亚洲青青久久| 日韩亚洲精品在线观看| 精品欠久久久中文字幕加勒比| 99久精品视频在线观看视频| 丝袜诱惑制服诱惑色一区在线观看| 国产高清亚洲| 亚洲深夜影院| 国产精品嫩模av在线| 亚洲欧洲日本mm| 国产日韩欧美一区二区三区在线观看| 天堂av在线| 欧美成人亚洲| 国产日韩一区二区三区在线 | 亚洲人成在线网站| 黄色在线观看www| 丝袜亚洲精品中文字幕一区| 亚洲欧洲美洲av| 欧美日韩99| 精品国产一区二区三区性色av| 久久国产小视频| 国产成人精品一区二区三区免费| 91久久久久| 日韩欧美四区| 韩日一区二区三区| 国产精品毛片久久久| 欧美日韩精品一本二本三本| 欧美激情网址| 免费的成人av| 亚洲精品在线影院| 福利一区视频| 亚洲+小说+欧美+激情+另类| 国产在线看片免费视频在线观看| 婷婷亚洲综合| 久久精品国产亚洲aⅴ| 亚洲一区亚洲| 欧美二三四区| 麻豆精品在线| 狂野欧美性猛交xxxx| 精品国产亚洲一区二区三区| 午夜在线精品| 欧美aa在线观看| 国产欧美久久一区二区三区| 亚洲成人三区| 国产色99精品9i| 免费久久精品| 欧美国产偷国产精品三区| 国产区精品区| 日韩区欧美区| 国产亚洲永久域名| 国产精品久久观看| 日韩激情啪啪| 免费视频久久| 国产一区二区精品| 久久久久久久久久久9不雅视频| 欧美国产亚洲精品| 国产一区二区高清| 欧美freesex黑人又粗又大| 免费一级欧美在线观看视频 | 首页欧美精品中文字幕| 国产视频欧美| 欧美a级片一区| 激情亚洲影院在线观看| 久久激情五月婷婷| 欧美激情福利| 国产精品免费大片| 久久福利影视| 91精品蜜臀一区二区三区在线| 97精品久久| 国产精品视频一区二区三区综合| 日韩国产欧美三级| 欧美综合国产| 久久久久久婷| 精品不卡一区| 久久精品网址| 国产成人久久精品一区二区三区| 国产精品久久久亚洲一区| 午夜在线精品偷拍| 怡红院精品视频在线观看极品| 国产精品日韩精品在线播放| 欧美激情福利| 美女性感视频久久| 人人爱人人干婷婷丁香亚洲| 一区二区三区四区在线观看国产日韩 | 日韩毛片一区| 亚洲一二av| 日韩精品视频网| 日本成人在线不卡视频| 国产图片一区| 精品久久网站| 国产aⅴ精品一区二区三区久久| 麻豆精品蜜桃视频网站| 超级白嫩亚洲国产第一| 欧美日韩在线观看首页| 午夜av成人| 日产精品一区二区| 国产综合婷婷| 蘑菇福利视频一区播放| 免费观看在线综合| 日韩高清不卡一区二区| 久久亚洲精品伦理| 婷婷精品在线| 国产精品久久久久久久久久久久久久久| 久久一区精品| 久久久久97| 国产精品久久免费视频| 日韩欧美1区| 免费高清在线一区| 蜜桃一区二区三区在线观看| 日韩高清不卡一区| 欧美国产小视频| 蜜桃久久av| 亚洲一区二区日韩| 日本综合精品一区| 国产成人精品免费视| 91精品电影| 国产精品婷婷| 久久激五月天综合精品| 国产在线日韩| 日本综合精品一区| 久久精品午夜| 在线天堂资源www在线污| 国内精品福利| 日韩精品福利一区二区三区| 精品国产麻豆| 精品久久99| 亚洲欧美日韩高清在线| 日韩激情视频网站| 日韩欧美视频专区| 午夜久久av | 免费视频一区二区三区在线观看| 日韩精品免费一区二区三区| 亚洲一二三区视频| 日韩av在线播放网址| 激情综合在线|