国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ES6 中Class創(chuàng)建對(duì)象與繼承實(shí)現(xiàn)

wind5o / 2322人閱讀

摘要:使用類創(chuàng)建實(shí)例對(duì)象也是直接對(duì)類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語法糖,同時(shí)有屬性和屬性,因此同時(shí)存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。

1 Class in ES6

ES6提出了類(Class)的概念,讓對(duì)象的原型的寫法更像面向?qū)ο笳Z言寫法。 ES6中通過class定義對(duì)象,默認(rèn)具有constructor方法和自定義方法,但是包含在class中的方法不可枚舉。

        class Point{
            constructor(){
            this.x=x;
            this.y=y;
            }
        toString(){
            return this.x+this.y;
            }
        }

注意:constructor方法對(duì)應(yīng)ES5的構(gòu)造函數(shù);創(chuàng)建類的方法不需要使用function關(guān)鍵字,方法之間不需要逗號(hào)分隔。

ES5中定義對(duì)象時(shí)組合使用構(gòu)造函數(shù)模式和原型模式,構(gòu)造函數(shù)模式用于定義實(shí)例屬性,原型模式用于定義共享方法和共享屬性,節(jié)省內(nèi)存,而且支持向構(gòu)造函數(shù)傳遞參數(shù)。

        function Point (x,y){
            this.x=x;
        this.y=y;
        }
        Point.prototype.toString= function(){
            return this.x+this.y;
        }
        
2 ES5和ES6創(chuàng)建實(shí)例和對(duì)象對(duì)比

1)ES5中的Person構(gòu)造函數(shù)和Person原型對(duì)象以及實(shí)例Person1、Person2的關(guān)系:構(gòu)造函數(shù)的prototype屬性以及實(shí)例的__proto__屬性指向原型對(duì)象,原型對(duì)象的constructor屬性指向構(gòu)造函數(shù)。

構(gòu)造函數(shù)的原型(prototype)屬性在ES6中依舊存在,這一點(diǎn)和ES5一樣:類的方法都定義在類的原型(prototype)上,在類的實(shí)例上面調(diào)用方法,其實(shí)就是調(diào)用原型上的方法。

    //實(shí)例的constructor方法就是類的原型(prototype)的constructor方法
    class B{
      constructor(){}
    }
    let b = new B();
    console.log(b.constructor === B.prototype.constructor);//true

2)ES6的類可以看做是構(gòu)造函數(shù)的另一種寫法(和ES5中構(gòu)造函數(shù)等同的并不是constructor方法):類是function類型,且類本身指向類的prototype對(duì)象的constructor屬性,這與ES5一樣。

        class Point{
          // ...
        }
        console.log(typeof Point) // "function"
        console.log(Point === Point.prototype.constructor) // true

3)使用類創(chuàng)建實(shí)例對(duì)象也是直接對(duì)類使用new命令,跟ES5中構(gòu)造函數(shù)的用法一致。

4)類內(nèi)部定義的方法都是不可枚舉的,這和ES5不同。

5)constructor方法
一個(gè)類必須有constructor方法,如果沒有就默認(rèn)添加constructor(){}。雖然類是函數(shù),但是和ES5不同,不通過new而直接調(diào)用類會(huì)導(dǎo)致類型錯(cuò)誤,也就是說這個(gè)函數(shù)僅當(dāng)在和new一起使用時(shí)才有意義。
6)類的實(shí)例
與ES5一樣,實(shí)例的屬性除非顯式定義在其本身(即定義在this對(duì)象上),否則都是定義在原型上(即定義在class上)。

            class Point {
              constructor(x, y) {
                this.x = x;
                this.y = y;
              }
              toString() {
                return "(" + this.x + ", " + this.y + ")";
              }
            }
            var point = new Point(2, 3);
            point.toString() // (2, 3)
            point.hasOwnProperty("x") // true
            point.hasOwnProperty("y") // true
            point.hasOwnProperty("toString") // false
            point.__proto__.hasOwnProperty("toString") // true

以上代碼中,x和y都是實(shí)例對(duì)象point自身的屬性(因?yàn)槎x在this變量上),所以hasOwnProperty方法返回true,而toString是原型對(duì)象的屬性(因?yàn)槎x在Point類上),所以hasOwnProperty方法返回false。這些都與ES5的行為保持一致。

與ES5一樣,類的所有實(shí)例共享一個(gè)原型對(duì)象。

        var p1 = new Point(2,3);
        var p2 = new Point(3,2);
        p1.__proto__ === p2.__proto__
        //true

可以通過實(shí)例的__proto__屬性為Class原型添加方法,增加后所有的原型都具有這個(gè)方法,這和ES5一樣。

        var p1 = new Point(2,3);
        var p2 = new Point(3,2);
        p1.__proto__.printName = function () { return "Oops" };
        p1.printName() // "Oops"
        p2.printName() // "Oops"

7)Class不存在變量提升(hoist),這一點(diǎn)與ES5完全不同。

        new Foo(); // ReferenceError
        class Foo {}

上面代碼中,F(xiàn)oo類使用在前,定義在后,這樣會(huì)報(bào)錯(cuò),因?yàn)镋S6不會(huì)把類的聲明提升到代碼頭部。這種規(guī)定的原因與繼承有關(guān),必須保證子類在父類之后定義。

8)嚴(yán)格模式
類和模塊的內(nèi)部,默認(rèn)就是嚴(yán)格模式,所以不需要使用use strict指定運(yùn)行模式。只要你的代碼寫在類或模塊之中,就只有嚴(yán)格模式可用。考慮到未來所有的代碼,其實(shí)都是運(yùn)行在模塊之中,所以ES6實(shí)際上把整個(gè)語言升級(jí)到了嚴(yán)格模式。

3 ES6 Class的繼承

Class通過extends關(guān)鍵字實(shí)現(xiàn)繼承,這和ES5通過修改原型鏈實(shí)現(xiàn)繼承不同(巧合的是,SASS也通過@extend實(shí)現(xiàn)樣式繼承):

        class ColorPoint extends Point{}

子類必須在constructor方法中調(diào)用super方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇悰]有自己的this對(duì)象,而是繼承父類的this對(duì)象,然后對(duì)其進(jìn)行加工。如果不調(diào)用super方法,子類就得不到this對(duì)象。

    class ColorPoint extends Point {
      constructor(x, y, color) {
        super(x, y); // 調(diào)用父類的constructor(x, y)
        this.color = color;
      }
      toString() {
        return this.color + " " + super.toString(); // super代表父類原型,調(diào)用父類的toString()
      }
    }

上面代碼中,constructor方法和toString方法之中,都出現(xiàn)了super關(guān)鍵字,它在這里表示父類的構(gòu)造函數(shù),用來新建父類的this對(duì)象。
super這個(gè)關(guān)鍵字,既可以當(dāng)作函數(shù)使用,也可以當(dāng)作對(duì)象使用。第一種情況,super作為函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù),只能用在子類的構(gòu)造函數(shù)中。ES6 要求,子類的構(gòu)造函數(shù)必須執(zhí)行一次super函數(shù)。第二種情況,super作為對(duì)象時(shí),指代父類的原型對(duì)象。

ES5的繼承,實(shí)質(zhì)是先創(chuàng)造子類的實(shí)例對(duì)象this,然后再將父類的方法添加到this上面(Parent.apply(this))。(ES5通過原型模式的繼承:創(chuàng)建子類,然后將父類的實(shí)例賦值給子類原型,也就是重寫子類原型,代之以一個(gè)新類型的實(shí)例。)ES6的繼承機(jī)制完全不同,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象this(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this。

如果子類沒有定義constructor方法,這個(gè)方法會(huì)被默認(rèn)添加。在子類的構(gòu)造函數(shù)中,只有調(diào)用super之后,才可以使用this關(guān)鍵字,否則會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇悓?shí)例的構(gòu)建,是基于對(duì)父類實(shí)例加工,只有super方法才能返回父類實(shí)例。

        class Point {
          constructor(x, y) {
            this.x = x;
            this.y = y;
          }
        }
        
        class ColorPoint extends Point {
          constructor(x, y, color) {
            this.color = color; // ReferenceError
            super(x, y);
            this.color = color; // 正確
          }
        }

和ES5一樣,通過子類創(chuàng)建的實(shí)例是父類以及子類的實(shí)例:

        let cp = new ColorPoint(25, 8, "green");
        
        cp instanceof ColorPoint // true
        cp instanceof Point // true
4 補(bǔ)充 1)類的prototype屬性和__proto__屬性(這段還沒看明白,太繞了。)

ES5中每一個(gè)對(duì)象都有__proto__屬性,指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性。ES6中沒有構(gòu)造函數(shù),Class作為構(gòu)造函數(shù)的語法糖,同時(shí)有prototype屬性和__proto__屬性,因此同時(shí)存在兩條繼承鏈。
(1)子類的__proto__屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。
(2)子類prototype屬性的__proto__屬性,表示方法的繼承,總是指向父類的prototype屬性。
這樣的結(jié)果是因?yàn)椋惖睦^承是按照下面的模式實(shí)現(xiàn)的。

        class A {
        }
        class B {
        }
        // B的實(shí)例繼承A的實(shí)例
        Object.setPrototypeOf(B.prototype, A.prototype);
        const b = new B();
        // B的實(shí)例繼承A的靜態(tài)屬性
        Object.setPrototypeOf(B, A);
        const b = new B();

這兩條繼承鏈,可以這樣理解:作為一個(gè)對(duì)象,子類(B)的原型(__proto__屬性)是父類(A);作為一個(gè)構(gòu)造函數(shù),子類(B)的原型(prototype屬性)是父類的實(shí)例。

2)Object.getPrototypeOf

Object.getPrototypeOf方法可以用來從子類上獲取父類。

        Object.getPrototypeOf(ColorPoint) === Point
        // true

因此,可以使用這個(gè)方法判斷,一個(gè)類是否繼承了另一個(gè)類。

3)實(shí)例的__proto__屬性

子類實(shí)例的__proto__屬性的__proto__屬性,指向父類實(shí)例的__proto__屬性。也就是說,子類實(shí)例的原型的原型,是父類實(shí)例的原型。

            
            var p1 = new Point(2, 3);
            var p2 = new ColorPoint(2, 3, "red");
            p2.__proto__ === p1.__proto__ // false
            p2.__proto__.__proto__ === p1.__proto__ // true

總的來說,ES6是對(duì)ES5的形式上的改變,真實(shí)內(nèi)容依舊不變,本質(zhì)上依舊是通過原型鏈實(shí)現(xiàn)繼承。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/50505.html

相關(guān)文章

  • ES6 Class創(chuàng)建對(duì)象繼承實(shí)現(xiàn)

    摘要:使用類創(chuàng)建實(shí)例對(duì)象也是直接對(duì)類使用命令,跟中構(gòu)造函數(shù)的用法一致。中沒有構(gòu)造函數(shù),作為構(gòu)造函數(shù)的語法糖,同時(shí)有屬性和屬性,因此同時(shí)存在兩條繼承鏈。子類的屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。 1 Class in ES6 ES6提出了類(Class)的概念,讓對(duì)象的原型的寫法更像面向?qū)ο笳Z言寫法。 ES6中通過class定義對(duì)象,默認(rèn)具有constructor方法和自定義方法,但是包含...

    zhou_you 評(píng)論0 收藏0
  • JavaScript基礎(chǔ): 類繼承

    摘要:類的方法相當(dāng)于之前我們定義在構(gòu)造函數(shù)的原型上。的構(gòu)造函數(shù)中調(diào)用其目的就是調(diào)用父類的構(gòu)造函數(shù)。是先創(chuàng)建子類的實(shí)例,然后在子類實(shí)例的基礎(chǔ)上創(chuàng)建父類的屬性。 前言   首先歡迎大家關(guān)注我的Github博客,也算是對(duì)我的一點(diǎn)鼓勵(lì),畢竟寫東西沒法獲得變現(xiàn),能堅(jiān)持下去也是靠的是自己的熱情和大家的鼓勵(lì)。    許久已經(jīng)沒有寫東西了,因?yàn)殡s七雜八的原因最近一直沒有抽出時(shí)間來把寫作堅(jiān)持下來,感覺和跑步一...

    liuchengxu 評(píng)論0 收藏0
  • ES6】更易于繼承的類語法

    摘要:的類使用熟悉的關(guān)鍵字指定類繼承的函數(shù),并且可以通過方法訪問父類的構(gòu)造函數(shù)。例如繼承一個(gè)的類繼承了,術(shù)語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實(shí)例,也是派生類的實(shí)例,內(nèi)建對(duì)象繼承的實(shí)用之處是改變返回對(duì)象的類型。 和其它面向?qū)ο缶幊陶Z言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態(tài)、派生、抽象、迭代、單例等,而且根據(jù) ES6 的新特性衍...

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

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

    sunnyxd 評(píng)論0 收藏0
  • JavaScript繼承理解:ES5繼承方式+ES6Class繼承對(duì)比

    摘要:寄生組合式繼承的繼承方式有多種主要有原型鏈繼承借用構(gòu)造函數(shù)組合式繼承寄生式繼承和寄生組合式繼承。中利用定義類,實(shí)現(xiàn)類的繼承子類里調(diào)用父類構(gòu)造函數(shù)實(shí)現(xiàn)實(shí)例屬性和方法的繼承子類原型繼承父類原型,實(shí)現(xiàn)原型對(duì)象上方法的繼承。 JavaScript中實(shí)現(xiàn)繼承 ??在JavaScript中實(shí)現(xiàn)繼承主要實(shí)現(xiàn)以下兩方面的屬性和方法的繼承,這兩方面相互互補(bǔ),既有共享的屬性和方法,又有特有的屬性和方法。 ...

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

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

0條評(píng)論

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