溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

再和“面向?qū)ο蟆闭剳賽?ài) - super(六)

發(fā)布時(shí)間:2020-07-21 21:01:08 來(lái)源:網(wǎng)絡(luò) 閱讀:749 作者:陳學(xué)輝 欄目:web開(kāi)發(fā)

在上一篇文章里介紹了繼承,那其中說(shuō)過(guò)一個(gè)很關(guān)鍵的東西想要繼承子類(lèi)里里必需先調(diào)用一個(gè)super方法。而super的作用絕對(duì)是價(jià)值連城!同時(shí)super的作用還有多種,并且跟你的使用環(huán)境有關(guān)系。

1、當(dāng)作函數(shù)使用

super被當(dāng)作函數(shù)使用,這種情況是最普遍的,上一篇文章里已經(jīng)使用過(guò)。它有以下幾種作用:

  1. super作為函數(shù)調(diào)用時(shí),代表父類(lèi)的構(gòu)造函數(shù)
  2. 調(diào)用super后,this會(huì)被改成子類(lèi)
  3. 只能用在構(gòu)造函數(shù)里,用在其它地方報(bào)錯(cuò)
{
    class Father{
        constructor(){
            console.log(new.target.name);
        }
    }
    class Son extends Father{
        constructor(){
            super();
            this.a=10;  //這里的this指向,Son的實(shí)例
        }
        method(){
            //super()   報(bào)錯(cuò),只能用在constructor里
        }
    }
    new Father();   //Father(new.target返回Father類(lèi))
    new Son();      //Son(new.target返回Son子類(lèi))
    console.log(new Son().a);   //10 this指向被修改成了子類(lèi)的實(shí)例
}

子類(lèi)里面并沒(méi)有寫(xiě)console.log,但是發(fā)現(xiàn)生成子類(lèi)實(shí)例后,控制臺(tái)里有輸出。說(shuō)明:super其實(shí)相當(dāng)于執(zhí)行了父級(jí)的constructor方法。同時(shí)彈出的結(jié)果是指向了子類(lèi),又說(shuō)明雖然調(diào)用的是父類(lèi)的構(gòu)造函數(shù),但是調(diào)用完后會(huì)指向子類(lèi),this指向也被改成了子類(lèi)的實(shí)例。其實(shí)supe的作用相當(dāng)于執(zhí)行Father.prototype.constructor.call(this);

2、當(dāng)作對(duì)象使用

super也可以被當(dāng)作對(duì)象使用,被當(dāng)作對(duì)象使用的時(shí)候情況有些復(fù)雜,跟上面是完全不一樣的,同時(shí)又按使用環(huán)境分為了兩種情況。

  1. 在普通方法中,指向父類(lèi)的原型對(duì)象
    • 只能調(diào)用原型里的東西
    • 如果調(diào)用的是方法,那方法內(nèi)部this指向子類(lèi)實(shí)例
    • 如果用super去添加屬性的話(huà),super就是this(實(shí)例)
  2. 在私有方法中,指向父類(lèi),而不是父類(lèi)的原型
    • 如果調(diào)用的是方法,那方法內(nèi)部this指向子類(lèi)而不是子類(lèi)實(shí)例

在普通方法中使用

此時(shí)切記用super去獲取跟設(shè)置時(shí)的指向完全不一樣

{
    class Father{
        constructor(){
            this.a='父類(lèi)實(shí)例的a';
            this.b='父類(lèi)實(shí)例的b';
        }
        showB(){
            console.log(`這是父類(lèi)身上的共享方法,并且會(huì)彈出${this.b}`);
        }
        static showB(){ //私有方法可以與上面的方法重名
            console.log(`這是父類(lèi)身上的私有方法,并且會(huì)彈出${this.b}`);
        }
    }
    Father.prototype.a='父類(lèi)原型的a';   //在原型身上的添加一個(gè)屬性a

    class Son extends Father{
        constructor(){
            super();    //這里的super是個(gè)方法,作用為引入父類(lèi)的構(gòu)造函數(shù)(當(dāng)作函數(shù)使用)
            this.b='子類(lèi)實(shí)例的b';

            //此處聲明:請(qǐng)按注釋標(biāo)的序號(hào)順序執(zhí)行代碼

            //
            /*
             *  3、super設(shè)置屬性
             *      1、用super設(shè)置屬性的話(huà),super就代表當(dāng)前環(huán)境的this。而當(dāng)前環(huán)境為子類(lèi)的constructor,所以此時(shí)的super代表的就是子類(lèi)的實(shí)例對(duì)象
             *      2、此時(shí)下面的showB()方法彈出的內(nèi)容為"這是父類(lèi)身上的共享方法,并且會(huì)彈出super就是this"是因?yàn)?,如果super為this的話(huà),那就與上面那段代碼重復(fù)了,后面覆蓋前面
             *
             */
            super.b='super就是this';

            /*
             *  4、super獲取屬性
             *      1、此時(shí)super的作用是獲取屬性,它依然指向父類(lèi)的原型對(duì)象所以下面這句話(huà)相當(dāng)于console.log(Father.prototype.b);所以結(jié)果為undefined。雖然在上面定義了super.b那也不會(huì)改變super的指向
             */
            console.log(super.b);     //undefined

            /*
             *  1、這里的super是一個(gè)對(duì)象,因?yàn)閏onstructor是個(gè)普通對(duì)象
             *      1、super指向父類(lèi)的原型對(duì)象,調(diào)用的是Father的共享方法showB()
             *      2、showB方法里的this指向子類(lèi)的實(shí)例,取的是Father的constructor里定義的b
             */
            super.showB();  //這是父類(lèi)身上的共享方法,并且會(huì)彈出子類(lèi)實(shí)例的b

            //2、super獲取屬性
            console.log(super.a);   //父類(lèi)原型的a   再次驗(yàn)證只能調(diào)用原型上的東西。原型上與constructor里都有個(gè)a,但是調(diào)的是原型上的
        }
    }
    Son.b='子類(lèi)的私有屬性b';
    new Son();
}

在私有方法中使用

此時(shí)切記用super的用法與在普通方法中的用法完全相反

{
    class Father{
        constructor(){
            this.b='父類(lèi)實(shí)例的b';
        }
        showB(){
            console.log(`這是父類(lèi)身上的共享方法,并且會(huì)彈出${this.b}`);
        }
        static showB(){ //這是個(gè)私有方法,與上面的方法重名是可以的
            console.log(`這是父類(lèi)身上的私有方法,并且會(huì)彈出${this.b}`);
        }
    }
    Father.prototype.b='父類(lèi)原型的b';   //在原型身上的添加一個(gè)屬性b

    class Son extends Father{
        constructor(){
            super();
            this.b='子類(lèi)實(shí)例的b';
        }

        /*
         *  1、這里的super是在私有方法里調(diào)用,所以指向父類(lèi),調(diào)用的是Father里定義的static showB方法
         *  2、此方法里的this指向被改成了子類(lèi),彈出的b是子類(lèi)的私有屬性b
         */
        static log(){
            super.showB();
        }
    }
    Son.b='子類(lèi)的私有屬性b';
    Son.log();  //這是子類(lèi)身上的私有方法,并且會(huì)彈出子類(lèi)的私有屬性b
}

忠告:要明確指定supe的類(lèi)型

super在用的時(shí)候必需指定它的類(lèi)型,不然不清不楚的去用,瀏覽器會(huì)給你報(bào)錯(cuò)!

{
    class Father{};
    class Son extends Father{
        constructor(){
            super();    //這個(gè)是作為函數(shù)
            //console.log(super);   //報(bào)錯(cuò)  那這個(gè)super它是個(gè)什么呢?它自己矛盾了,瀏覽器迷茫了~
            console.log(super.a);   //這個(gè)是作為對(duì)象
        }
    }
}

下一篇,實(shí)戰(zhàn)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI