资讯专栏INFORMATION COLUMN

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

Towers / 1772人阅读

摘要:同时弹出的结果是指向了子类,又说明虽然调用的是父类的构造函数,但是调用完后会指向子类,指向也被改成了子类的实例。

在上一篇文章里介绍了继承,那其中说过一个很关键的东西想要继承子类里里必需先调用一个super方法。而super的作用绝对是价值连城!同时super的作用还有多种,并且跟你的使用环境有关系。

1、当作函数使用

super被当作函数使用,这种情况是最普遍的,上一篇文章里已经使用过。它有以下几种作用:

super作为函数调用时,代表父类的构造函数

调用super后,this会被改成子类

只能用在构造函数里,用在其它地方报错

{
    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也可以被当作对象使用,被当作对象使用的时候情况有些复杂,跟上面是完全不一样的,同时又按使用环境分为了两种情况。

在普通方法中,指向父类的原型对象

* 只能调用原型里的东西
* 如果调用的是方法,那方法内部this指向子类实例
* 如果用super去添加属性的话,super就是this(实例)

在私有方法中,指向父类,而不是父类的原型

* 如果调用的是方法,那方法内部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);   //这个是作为对象
        }
    }
}

下一篇,实战!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96654.html

相关文章

  • 再和面向对象恋爱 - 图片预加载组件(七)

    摘要:源码下载至此再和面向对象谈恋爱系列文章已经全部更新完毕写文章不易,且行且珍惜 再和面向对象谈恋爱 - 对象简介(一)再和面向对象谈恋爱 - 对象相关概念(二)再和面向对象谈恋爱 - 面向对象编程概念(三)再和面向对象谈恋爱 - class(四)再和面向对象谈恋爱 - 继承(五)再和面向对象谈恋爱 - super(六) 通过前面的六篇文章已经把ES6的面向对象跟大伙说清楚了,大家最关心的...

    caoym 评论0 收藏0
  • 再和面向对象恋爱 - 继承(五)

    摘要:面向对象里最大的特点应该就属继承了。在第二篇文章里说过原型实例跟构造函数之间的继承,并且还讲了一道推算题。 通过上一篇文章想必各位老铁已经熟悉了class了,这篇文章接着介绍继承。面向对象里最大的特点应该就属继承了。一个项目可能需要不断的迭代、完善、升级。那每一次的更新你是要重新写呢,还是在原有的基础上改吧改吧呢?当然,不是缺心眼的人肯定都会在原来的基础上改吧改吧,那这个改吧改吧就需要...

    Airmusic 评论0 收藏0
  • 再和面向对象恋爱 - 面向对象编程概念(三)

    摘要:说到底面向对象才是程序语言的根本。其实面向对象编程说的就是自定义对象。里并没有类的概念,所以严格上来讲这是个假的面向对象里的面向对象编程现在好了,终于听到别人鄙视我们了,给我们提供了类这个概念,其实是向传统语言更靠齐了。 通过前两篇文章,我们了解了对象的概念以及面向对象里的相关概念等知识,那前面说了对象分类里的前两种,这篇文章要详细去说第三种自定义对象,那真正的好戏这就来了! 面向对象...

    Cruise_Chan 评论0 收藏0
  • 再和面向对象恋爱 - class(四)

    摘要:在上一篇文章里我介绍了一下面向对象编程的概念,在最后终于喜出望外看到了提供了类的概念了。而到了里面真正的类与构造函数现在是分离的,通过上面的代码可以看出来,这种写法正是面向对象的正统写法。 在上一篇文章里我介绍了一下面向对象编程的概念,在最后终于喜出望外看到了ES6提供了类的概念了。那这个类如何去用,是这篇文章的主题。ES6给我们提供了一个class关键字。这个关键字跟以前的var l...

    刘东 评论0 收藏0
  • 再和面向对象恋爱 - 对象相关概念(二)

    摘要:所有的对象都是由构造函数创建的对象哪来的构造函数生的。而普通函数不能生成对象不孕不育,构造函数可以生成对象有生育能力。别急,记住那句话永远指向实例对象对应的构造函数的,那就先看实例对象是谁。 上一篇文章把对象的概念讲解了一下,这篇文章要重点解释最让大家犯迷糊的一些概念,包括 构造函数 实例 继承 构造函数的属性与方法(私有属性与方法) 实例的属性与方法(共享属性与方法) protot...

    qpwoeiru96 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<