欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳述JavaScript實現(xiàn)繼承的幾種方式(推薦)

 更新時間:2016年03月22日 12:03:24   作者:YvetteLau  
這篇文章主要介紹了詳述JavaScript實現(xiàn)繼承的幾種方式(推薦)的相關(guān)資料,需要的朋友可以參考下

ECMAScript只支持實現(xiàn)繼承,而且其實現(xiàn)繼承主要是依靠原型鏈來實現(xiàn)的。

原型鏈

原型鏈的基本思想是利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。每一個構(gòu)造函數(shù)都有一個原型對象,原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實例都包含一個指向原型對象的指針。如果:我們讓原型對象A等于另一個類型B的實例,那么原型對象A就會有一個指針指向B的原型對象,相應(yīng)的B的原型對象中保存著指向其構(gòu)造函數(shù)的指針。假如B的原型對象又是另一個類型的實例,那么上述的關(guān)系依舊成立,如此層層遞進,就構(gòu)成了實例與原型的鏈條。

這里寫圖片描述 

實例以及構(gòu)造函數(shù)和原型之間的關(guān)系圖如下所示:

這里寫圖片描述 

person.constructor現(xiàn)在指向的是Parent,這是因為Child.prototype指向了Parent的原型,而Parent原型對象的constructor指向Parent。

當以讀取模式訪問一個實例屬性時,首先會在實例中搜索該屬性,如果沒有找到該屬性,則會繼續(xù)搜索實例的原型。在通過原型鏈實現(xiàn)的集成中,搜索過程就會沿著原型鏈繼續(xù)向上,直到搜索到原型鏈的末端。

例如,調(diào)用person.getParentValue()方法,1)搜索實例;2)搜索Child.prototype;3)搜索Parent.prototype;找到了getParentValue()方法停止。

1、默認的原型

前面的例子中展示的原型鏈少了一環(huán),所有引用類型默認都繼承了Object,而這個繼承也是通過原型鏈實現(xiàn)的。因此默認的原型都包含一個內(nèi)部指針,指向Object.prototype,這也正是所有自定義類型會繼承toString()、ValueOf()等默認方法的根本原因。換句話說Object.prototype就是原型鏈的末端。

這里寫圖片描述 

2、確定原型和實例的關(guān)系

通過兩種方式可以確定原型和實例之間的關(guān)系,第一種是使用instanceOf操作符,第二種是使用isPrototypeOf()方法。
實例 instanceOf 原型鏈 中出現(xiàn)過的構(gòu)造函數(shù),都會返回true

console.log(person instanceOf Child);//true 

console.log(person instanceOf Parent);//true 
console.log(person instanceOf Object);//true 
isPrototype(),只要是原型鏈中出現(xiàn)過的原型,都可以說是該原型鏈所派生出來的實例的原型,因此也返回true. 
console.log(Object.prototype.isPrototypeOf(instance));//true 
console.log(Parent.prototype.isPrototypeOf(instance));//true 
console.log(Child.prototype.isPrototypeOf(instance));//true 

3、謹慎地定義方法

子類型有時候需要覆蓋超類型中的某個方法,或者需要添加超類型中不存在的莫個方法,注意:給原型添加方法的代碼一定要放在替換原型的語句之后。

當通過Child的實例調(diào)用getParentValue()時,調(diào)用的是這個重新定義過的方法,但是通過Parent的實例調(diào)用getParentValue()時,調(diào)用的還是原來的方法。

格外需要注意的是:必須要在Parent的實例替換原型之后,再定義這兩個方法。

還有一點需要特別注意的是:通過原型鏈實現(xiàn)繼承時,不能使用對象字面量創(chuàng)建原型方法,因為這樣做會重寫原型鏈。

這里寫圖片描述 

以上代碼剛把Parent的實例賦值給Child的原型對象,緊接著又將原型替換成一個字面量,替換成字面量之后,Child原型實際上包含的是一個Object的實例,而不再是Parent的實例,因此我們設(shè)想中的原型鏈被切斷.Parent和Child之間沒有任何關(guān)聯(lián)。

4、原型鏈的問題

原型鏈很強大,可以利用它來實現(xiàn)繼承,但是也有一些問題,主要的問題還是包含引用類型值的原型屬性會被所有實例共享。因此我們在構(gòu)造函數(shù)中定義實例屬性。但是在通過原型來實現(xiàn)繼承時,原型對象其實變成了另一個類型的實例。于是原先定義在構(gòu)造函數(shù)中的實例屬性變成了原型屬性了。

舉例說明如下:

這里寫圖片描述 

在Parent構(gòu)造函數(shù)中定義了一個friends屬性,該屬性值是一個數(shù)組(引用類型值)。這樣,Parent的每個實例都會各自包含自己的friends屬性。當Child通過原型鏈繼承了Parent之后,Child.prototype也用用了friends屬性——這就好像friends屬性是定義在Child.prototype一樣。這樣Child的所有實例都會共享這個friends屬性,因此我們對kid1.friends做的修改,在kid2.friends中也會體現(xiàn)出來,顯然,這不是我們想要的。

原型鏈的另一個問題是:在創(chuàng)建子類型的實例時,不能在不影響所有對象實例的情況下,給超類型的構(gòu)造函數(shù)傳遞參數(shù)。因此,我們通常很少會單獨使用原型鏈。

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

為了解決原型中包含引用類型值帶來的一些問題,引入了借用構(gòu)造函數(shù)的技術(shù)。這種技術(shù)的基礎(chǔ)思想是:在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型構(gòu)造函數(shù)。

這里寫圖片描述 

Parent.call(this)在新創(chuàng)建的Child實例的環(huán)境下調(diào)用了Parent構(gòu)造函數(shù)。在新創(chuàng)建的Child實例環(huán)境下調(diào)用Parent構(gòu)造函數(shù)。這樣,就在新的Child對象上,此處的kid1和kid2對象上執(zhí)行Parent()函數(shù)中定義的對象初始化代碼。這樣,每個Child實例就都會具有自己的friends屬性的副本了。

借用構(gòu)造函數(shù)的方式可以在子類型的構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)。

這里寫圖片描述 

為了確保子類型的熟悉不會被父類的構(gòu)造函數(shù)重寫,可以在調(diào)用父類構(gòu)造函數(shù)之后,再添加子類型的屬性。
構(gòu)造函數(shù)的問題:

構(gòu)造函數(shù)模式的問題,在于方法都在構(gòu)造函數(shù)中定義,函數(shù)復(fù)用無從談起,因此,借用構(gòu)造函數(shù)的模式也很少單獨使用。

組合繼承

組合繼承指的是將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合在一塊,從而發(fā)揮二者之長。即:使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實現(xiàn)對實例屬性的繼承。

這里寫圖片描述 

Person構(gòu)造函數(shù)定義了兩個屬性:name和friends。Person的原型定義了一個方法sayName()。Child構(gòu)造函數(shù)在調(diào)用Parent構(gòu)造函數(shù)時,傳入了name參數(shù),緊接著又定義了自己的屬性age。然后將Person的實例賦值給Child的原型,然后又在該原型上定義了方法sayAge().這樣,兩個不同的Child實例既分別擁有自己的屬性,包括引用類型的屬性,又可以使用相同的方法了。
組合繼承避免了原型鏈和構(gòu)造函數(shù)的缺陷,融合了他們的有點,成為JavaScript中最常用的繼承模式。而且,instanceOf和isPropertyOf()也能夠識別基于組合繼承創(chuàng)建的對象。

最后,關(guān)于JS對象和繼承都還有幾種模式?jīng)]有寫,或者說,我自己也還未去深刻研究,但是,我想,首先將組合模式應(yīng)用的游刃有余。并且,對于為何選用組合模式,知其然,知其所以然。

關(guān)于JavaScript實現(xiàn)繼承的幾種方式(推薦),小編就給大家介紹到這里,希望對大家有所幫助!

相關(guān)文章

  • JavaScript實現(xiàn)酷炫的鼠標拖尾特效

    JavaScript實現(xiàn)酷炫的鼠標拖尾特效

    這篇文章主要為大家介紹了通過JavaScript實現(xiàn)的一個超級好看的鼠標拖尾特效,文中的示例代碼講解詳細,對我們學習JavaScript有一定的幫助,感興趣的可以學習一下
    2021-12-12
  • 支付寶小程序從手動埋點到自動埋點的實現(xiàn)過程

    支付寶小程序從手動埋點到自動埋點的實現(xiàn)過程

    埋點的意思是在你想要的數(shù)據(jù)節(jié)點出進行設(shè)置,可以方便進行采集,下面這篇文章主要給大家介紹了關(guān)于支付寶小程序從手動埋點到自動埋點的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • js中時間格式化的幾種方法

    js中時間格式化的幾種方法

    這篇文章給大家分享了關(guān)于js中時間格式化的幾種方法,有需要的朋友們可以參考學習下。
    2018-07-07
  • js設(shè)置組合快捷鍵/tabindex功能的方法

    js設(shè)置組合快捷鍵/tabindex功能的方法

    本文主要介紹用js設(shè)置tabindex功能和js設(shè)置組合快捷鍵的方法,很簡單,這樣可以增強用戶體驗,方法就在下面
    2013-11-11
  • 微信小程序API—獲取定位的詳解

    微信小程序API—獲取定位的詳解

    這篇文章主要介紹了微信小程序API獲取定位,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • 多附件上傳組件演示

    多附件上傳組件演示

    多附件上傳組件演示...
    2006-09-09
  • JS中Location使用詳解

    JS中Location使用詳解

    javascript中 location用于獲取或設(shè)置窗體的URL,并且可以用于解析URL,是BOM中最重要的對象之一,下面我們就來詳細探討下Location對象的使用。
    2015-05-05
  • layui 實現(xiàn)加載動畫以及非真實加載進度的方法

    layui 實現(xiàn)加載動畫以及非真實加載進度的方法

    今天小編就為大家分享一篇layui 實現(xiàn)加載動畫以及非真實加載進度的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • JavaScript iframe 實現(xiàn)多窗口通信實例詳解

    JavaScript iframe 實現(xiàn)多窗口通信實例詳解

    這篇文章主要為大家介紹了JavaScript iframe 實現(xiàn)多窗口通信實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • js改變img標簽的src屬性在IE下沒反應(yīng)的解決方法

    js改變img標簽的src屬性在IE下沒反應(yīng)的解決方法

    在Chrome FF里都能改變成功,但在IE下卻不行,網(wǎng)上搜了半天,大概了解了,這個是IE的一個bug,具體的解決方法如下,有類似問題的朋友可以參考下哈,希望對大家有所幫助
    2013-07-07

最新評論