亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JS-繼承(es5,es6)

AZmake / 1500人閱讀

摘要:組合式繼承是最常用的繼承模式,但組合繼承使用過(guò)程中會(huì)被調(diào)用兩次一次是創(chuàng)建子類(lèi)型的時(shí)候,另一次是在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部。

首先需要了解原型鏈機(jī)制: 原型鏈作為實(shí)現(xiàn)繼承的主要方法,其基本思想就是利用原型讓一個(gè)引用類(lèi)型繼承另 一個(gè)引用類(lèi)型的屬性和方法.

構(gòu)造函數(shù)、原型、實(shí)例之間的關(guān)系: 每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象(prototype),原型對(duì)象都包含一個(gè)指向構(gòu)造函數(shù)的指針(constructor),而實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針(__propto__).

自我理解: 其實(shí)每個(gè)Function都是Object基類(lèi)的一個(gè)實(shí)例,所以每個(gè)Function上都有一個(gè)__proto__指向了Object.prototype.當(dāng)查找一個(gè)實(shí)例的屬性時(shí),會(huì)先從這個(gè)實(shí)例的自定義屬性上找,如果沒(méi)有的話通過(guò)__proto__去實(shí)例所屬類(lèi)的原型上去找,如果還沒(méi)有的話再通過(guò)原型(原型也是對(duì)象,只要是對(duì)象就有__proto__屬性)的__proto__到Object的原型上去找,一級(jí)一級(jí)的找,如果沒(méi)有就undefined(Object的__proto__返回undefined).

(一) 原型鏈繼承 :
 function Parent(name) { 
    this.name = name;
 }
 Parent.prototype.printName = function() {
    console.log("parent name:", this.name);
}
function Child(name) {
    this.name = name;
}
Child.prototype = new Parent("father");
Child.prototype.constructor = Child;//由于Child.prototype繼承Parent,導(dǎo)致constructor丟失
Child.prototype.printName = function() {
    console.log("child name:", this.name);
}
var child = new Child("son");
child.sayName();    // child name: son

這種方法存在兩個(gè)缺點(diǎn):

1.子類(lèi)型無(wú)法給超類(lèi)型傳遞參數(shù);
2.Child.prototype.sayName 必須寫(xiě)在 Child.prototype = new Parent("father"); 
之后,不然就會(huì)被覆蓋掉。
(二) 類(lèi)式繼承:
 function Parent(name) { 
    this.name = name;
 }
 Parent.prototype.printName = function() {
    console.log("parent name:", this.name);
 }
 Parent.prototype.doSomthing = function() {
    console.log("parent do something!");
 }
function Child(name, parentName) {
    Parent.call(this, parentName);
    this.name = name;
}
Child.prototype.printName = function() {
    console.log("child name:", this.name);
}
var child = new Child("son");
child.printName();   // child name: son
child.doSomthing();   // TypeError: child.doSomthing is not a function

相當(dāng)于 Parent 這個(gè)函數(shù)在 Child 函數(shù)中執(zhí)行了一遍,并且將所有與 this 綁定的變量都切換到了 Child 上,這樣就克服了第一種方式帶來(lái)的問(wèn)題。
缺點(diǎn):沒(méi)有原型,每次創(chuàng)建一個(gè) Child 實(shí)例對(duì)象時(shí)候都需要執(zhí)行一遍 Parent 函數(shù),無(wú)法復(fù)用一些公用函數(shù)。

(三) 組合式繼承:前兩種方式的結(jié)合
function Parent(name) {

    this.name = name;
}

Parent.prototype.printName = function() {
    console.log("parent name:", this.name);
}
Parent.prototype.doSomething = function() {
    console.log("parent do something!");
}
function Child(name, parentName) {
    Parent.call(this, parentName);// 第二次調(diào)用
    this.name = name;
}

Child.prototype = new Parent();// 第一次調(diào)用      
Child.prototype.constructor = Child;
Child.prototype.printName = function() {
    console.log("child name:", this.name);
}

var child = new Child("son");
child.printName();    // child name: son
child.doSomething();   // parent do something!

組合式繼承是比較常用的一種繼承方法,其背后的思路是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過(guò)借用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。

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

組合式繼承是 JS 最常用的繼承模式,但組合繼承使用過(guò)程中會(huì)被調(diào)用兩次:一次是創(chuàng)建子類(lèi)型的時(shí)候,另一次是在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部。

第一次調(diào)用構(gòu)造函數(shù)顯然是沒(méi)有必要的,因?yàn)榈谝淮握{(diào)用構(gòu)造函數(shù)時(shí)候不需要函數(shù)內(nèi)部的那些實(shí)例屬性,這么寫(xiě)只是想獲得其原型上的方法罷了,所以這時(shí)候你可能會(huì)這樣寫(xiě):

Child.prototype = Parent.prototype;

這樣寫(xiě)顯然是不對(duì)的:
1.首先,你這樣寫(xiě)的話相當(dāng)于是子類(lèi)和父類(lèi)都指向同一個(gè)對(duì)象,這時(shí)候如果你添加了新的方法給 Child 但實(shí)際上 Parent 并不需要,相當(dāng)于強(qiáng)行給 Parent 添加了一個(gè)未知的方法。
2.其次,仔細(xì)想想,這樣體現(xiàn)不出繼承的多態(tài)性,比如此時(shí)子類(lèi)想要重寫(xiě)父類(lèi)的 getName 的方法,那么父類(lèi)的方法也就會(huì)隨之修改,這顯然違背了多態(tài)性。

也就是說(shuō)我們第一次調(diào)用構(gòu)造函數(shù)的時(shí)候,其實(shí)是不管構(gòu)造函數(shù)里面的內(nèi)容,這是我們可以new一個(gè)空函數(shù),將其prototype指向Parent.prototype,代碼如下:

(四) 寄生組合式繼承:
function Parent(name) {
    this.name = name;
}
Parent.prototype.printName = function() {
    console.log("parent name:", this.name);
}

function Child(name, parentName) {
    Parent.call(this, parentName);  
    this.name = name;    
}

function inheritPrototype(Parent, Child) {
    Child.prototype = Object.create(Parent.prototype);   //修改
    Child.prototype.constructor = Child;
}

inheritPrototype(Parent, Child);
Child.prototype.printName = function() {
    console.log("child name:", this.name);
}
Child.prototype.constructor = Child;

var parent = new Parent("father");
parent.printName();    // parent name: father

var child = new Child("son", "father");
child.printName();     // child name: son
(五) ES 6 繼承:
class Parent {
    constructor(name) {
        this.name = name;
    }
    doSomething() {
        console.log("parent do something!");
    }
    printName() {
        console.log("parent name:", this.name);
    }
}

class Child extends Parent {
    constructor(name, parentName) {
        super(parentName);
        this.name = name;
    }
    printName() {
         console.log("child name:", this.name);
    }
}
const child = new Child("son", "father");
child.printName();            // child name: son
child.doSomething();        // parent do something!
const parent = new Parent("father");
parent.printName();           // parent name: father
    

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97881.html

相關(guān)文章

  • 為什么都說(shuō)js 里面任何對(duì)象最終都繼承了Object對(duì)象

    摘要:今天閑來(lái)無(wú)事,看見(jiàn)幾行小字。又說(shuō)所有對(duì)象,繼承終是。強(qiáng)行押韻一波這首詩(shī)的意思就是說(shuō)的我今天沒(méi)有什么事情,然后無(wú)意中又在網(wǎng)上看到了任何對(duì)象都是從對(duì)象繼承而來(lái)的這句話。一時(shí)興起,便去驗(yàn)證這句話。 今天閑來(lái)無(wú)事,看見(jiàn)幾行小字。又說(shuō)所有對(duì)象,繼承終是Obj?!?強(qiáng)行押韻一波 這首詩(shī)的意思就是說(shuō)的我今天沒(méi)有什么事情,然后無(wú)意中又在網(wǎng)上看到了任何對(duì)象都是從Object對(duì)象繼承而來(lái)的這句話。一時(shí)興...

    Gemini 評(píng)論0 收藏0
  • JS繼承ES5 & ES6

    摘要:繼承可以使得子類(lèi)具有父類(lèi)別的各種屬性和方法。繼承是類(lèi)與類(lèi)之間的關(guān)系。繼承的實(shí)質(zhì)就是兩次的原型搜索,像是實(shí)例屬性而不是繼承,才是繼承。更多用法見(jiàn)繼承。 前言 面試中最常會(huì)問(wèn)到的問(wèn)題:什么是繼承?如何分別用 ES5 和 ES6 實(shí)現(xiàn)?想要學(xué)習(xí)繼承,必須先學(xué)好原型與原型鏈,如果此部分還不清楚,請(qǐng)先學(xué)習(xí)此部分再來(lái)閱讀本文,可參考我的文章JS之原型與原型鏈或?yàn)g覽其他相關(guān)的學(xué)習(xí)網(wǎng)站。 定義 繼承...

    antyiwei 評(píng)論0 收藏0
  • 學(xué)習(xí) __es5es6繼承的區(qū)別

    摘要:前奏的構(gòu)造函數(shù)就是函數(shù)的本身正文的繼承是通過(guò)函數(shù)結(jié)合原型而實(shí)現(xiàn)的,繼承是先實(shí)例化父類(lèi)直接繼承使用這個(gè)詞來(lái)定義類(lèi)的構(gòu)造函數(shù)是函數(shù)的繼承用與繼承是實(shí)例化子類(lèi)對(duì)象的時(shí)候繼承父類(lèi)然后繼承 最開(kāi)始接觸的時(shí)候es5,js的類(lèi)概念是 通過(guò)函數(shù) 實(shí)現(xiàn)的。 前奏:showImg(https://segmentfault.com/img/bVbuYHF?w=468&h=345);es5的構(gòu)造函數(shù)就...

    hqman 評(píng)論0 收藏0
  • 如何繼承Date對(duì)象?由一道題徹底弄懂JS繼承

    摘要:前言見(jiàn)解有限,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出,如有錯(cuò)誤,會(huì)及時(shí)修正。倘若用的是中文搜索。所以最終的實(shí)例對(duì)象仍然能進(jìn)行正常的原型鏈回溯,回溯到原本的所有原型方法這樣通過(guò)一個(gè)巧妙的欺騙技巧,就實(shí)現(xiàn)了完美的繼承。 前言 見(jiàn)解有限,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出,如有錯(cuò)誤,會(huì)及時(shí)修正。 20180201更新: 修改用詞描述,如組合寄生式改成寄生組合式,修改多處筆誤(感謝@Yao Ding的...

    sunnyxd 評(píng)論0 收藏0
  • ES6,你不得不學(xué)!

    摘要:但是,的本質(zhì)仍然是函數(shù),是構(gòu)造函數(shù)的另外一種寫(xiě)法。報(bào)錯(cuò)原生構(gòu)造函數(shù)的繼承對(duì)于一些原生的構(gòu)造函數(shù),比如,,,等,在是無(wú)法通過(guò)方法實(shí)現(xiàn)原生函數(shù)的內(nèi)部屬性,原生函數(shù)內(nèi)部的無(wú)法綁定,內(nèi)部屬性獲得不了。 在沒(méi)有學(xué)習(xí) ES6 之前,學(xué)習(xí) React,真的是一件非常痛苦的事情。即使之前你對(duì) ES5 有著很好的基礎(chǔ),包括閉包、函數(shù)、原型鏈和繼承,但是 React 中已經(jīng)普遍使用 ES6 的語(yǔ)法,包括 ...

    CKJOKER 評(píng)論0 收藏0
  • JavaScript 原型系統(tǒng)的變遷,以及 ES6 class

    摘要:一般我們對(duì)這種構(gòu)造函數(shù)命名都會(huì)采用,并把它稱呼為類(lèi),這不僅是為了跟的理念保持一致,也是因?yàn)榈膬?nèi)建類(lèi)也是這種命名。由生成的對(duì)象,其是。這是標(biāo)準(zhǔn)的規(guī)定。本文的主題是原型系統(tǒng)的變遷,所以并沒(méi)有涉及和對(duì)原型鏈的影響。 概述 JavaScript 的原型系統(tǒng)是最初就有的語(yǔ)言設(shè)計(jì)。但隨著 ES 標(biāo)準(zhǔn)的進(jìn)化和新特性的添加。它也一直在不停進(jìn)化。這篇文章的目的就是梳理一下早期到 ES5 和現(xiàn)在 ES6,...

    chuyao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<