再和“面向对象”谈恋爱 - super(六)

上一篇文章里引见了继续,那个中说过一个很症结的东西想要继续子类里里必须先挪用一个super要领。而super的作用相对是无价之宝!同时super的作用另有多种,而且跟你的运用环境有关联。

1、看成函数运用

super被看成函数运用,这类状况是最广泛的,上一篇文章里已运用过。它有以下几种作用:

  1. super作为函数挪用时,代表父类的组织函数
  2. 挪用super后,this会被改成子类
  3. 只能用在组织函数里,用在别的处所报错
{
    class Father{
        constructor(){
            console.log(new.target.name);
        }
    }
    class Son extends Father{
        constructor(){
            super();
            this.a=10;  //这里的this指向,Son的实例
        }
        method(){
            //super()    报错,只能用在constructor里
        }
    }
    new Father();    //Father(new.target返回Father类)
    new Son();        //Son(new.target返回Son子类)
    console.log(new Son().a);   //10 this指向被修正成了子类的实例
}

子类内里并没有写console.log,然则发明天生子类实例后,控制台里有输出。申明:super实在相当于实行了父级的constructor要领。同时弹出的效果是指向了子类,又申明虽然挪用的是父类的组织函数,然则挪用完后会指向子类,this指向也被改成了子类的实例。实在supe的作用相当于实行Father.prototype.constructor.call(this);

2、看成对象运用

super也能够被看成对象运用,被看成对象运用的时刻状况有些庞杂,跟上面是完整不一样的,同时又按运用环境分为了两种状况。

  1. 在一般要领中,指向父类的原型对象
* 只能挪用原型里的东西
* 假如挪用的是要领,那要领内部this指向子类实例
* 假如用super去增加属性的话,super就是this(实例)
  1. 在私有要领中,指向父类,而不是父类的原型
* 假如挪用的是要领,那要领内部this指向子类而不是子类实例

在一般要领中运用

此时牢记用super去猎取跟设置时的指向完整不一样

{
    class Father{
        constructor(){
            this.a='父类实例的a';
            this.b='父类实例的b';
        }
        showB(){
            console.log(`这是父类身上的同享要领,而且会弹出${this.b}`);
        }
        static showB(){    //私有要领能够与上面的要领重名
            console.log(`这是父类身上的私有要领,而且会弹出${this.b}`);
        }
    }
    Father.prototype.a='父类原型的a';   //在原型身上的增加一个属性a
    
    class Son extends Father{
        constructor(){
            super();    //这里的super是个要领,作用为引入父类的组织函数(看成函数运用)
            this.b='子类实例的b';
            
            //此处声明:请按解释标的序号递次实行代码
            
            //
            /*
             *  3、super设置属性
             *      1、用super设置属性的话,super就代表当前环境的this。而当前环境为子类的constructor,所以此时的super代表的就是子类的实例对象
             *      2、此时下面的showB()要领弹出的内容为"这是父类身上的同享要领,而且会弹出super就是this"是由于,假如super为this的话,那就与上面那段代码反复了,背面掩盖前面
             *
             */
            super.b='super就是this';
            
            
            /*
             *  4、super猎取属性
             *      1、此时super的作用是猎取属性,它依旧指向父类的原型对象所以下面这句话相当于console.log(Father.prototype.b);所以效果为undefined。虽然在上面定义了super.b那也不会转变super的指向
             */
            console.log(super.b);      //undefined
            
            
            /*
             *  1、这里的super是一个对象,由于constructor是个一般对象
             *      1、super指向父类的原型对象,挪用的是Father的同享要领showB()
             *      2、showB要领里的this指向子类的实例,取的是Father的constructor里定义的b
             */
            super.showB();    //这是父类身上的同享要领,而且会弹出子类实例的b
            
            
            //2、super猎取属性
            console.log(super.a);   //父类原型的a   再次考证只能挪用原型上的东西。原型上与constructor里都有个a,然则调的是原型上的
        }
    }
    Son.b='子类的私有属性b';
    new Son();
}

在私有要领中运用

此时牢记用super的用法与在一般要领中的用法完整相反

{
    class Father{
        constructor(){
            this.b='父类实例的b';
        }
        showB(){
            console.log(`这是父类身上的同享要领,而且会弹出${this.b}`);
        }
        static showB(){    //这是个私有要领,与上面的要领重名是能够的
            console.log(`这是父类身上的私有要领,而且会弹出${this.b}`);
        }
    }
    Father.prototype.b='父类原型的b';   //在原型身上的增加一个属性b
    
    class Son extends Father{
        constructor(){
            super();
            this.b='子类实例的b';
        }
        
        /*
         *  1、这里的super是在私有要领里挪用,所以指向父类,挪用的是Father里定义的static showB要领
         *  2、此要领里的this指向被改成了子类,弹出的b是子类的私有属性b
         */
        static log(){
            super.showB();
        }
    }
    Son.b='子类的私有属性b';
    Son.log();    //这是子类身上的私有要领,而且会弹出子类的私有属性b
}

忠言:要明白指定supe的范例

super在用的时刻必须指定它的范例,不然不清不楚的去用,浏览器会给你报错!

{
    class Father{};
    class Son extends Father{
        constructor(){
            super();    //这个是作为函数
            //console.log(super);    //报错  那这个super它是个什么呢?它自己抵牾了,浏览器渺茫了~
            console.log(super.a);   //这个是作为对象
        }
    }
}

下一篇,实战!

    原文作者:kaivon
    原文地址: https://segmentfault.com/a/1190000015906897
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞