再和“面向对象”谈恋爱 - 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(实例)
  2. 在私有方法中,指向父类,而不是父类的原型
    • 如果调用的是方法,那方法内部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);   //这个是作为对象
        }
    }
}

下一篇,实战!请添加链接描述

原文地址:http://blog.51cto.com/13258913/2145217

时间: 2024-11-09 06:40:35

再和“面向对象”谈恋爱 - super(六)的相关文章

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

再和"面向对象"谈恋爱 - 对象简介(一)再和"面向对象"谈恋爱 - 对象相关概念(二)再和"面向对象"谈恋爱 - 面向对象编程概念(三)再和"面向对象"谈恋爱 - class(四)再和"面向对象"谈恋爱 - 继承(五)再和"面向对象"谈恋爱 - super(六) 通过前面的六篇文章已经把ES6的面向对象跟大伙说清楚了,大家最关心的应该是来个例子实战一下,别担心自行车都会有.那这篇文章通

再和“面向对象”谈恋爱 - 对象简介(一)

JavaScript中的面向对象是个老生常谈的话题,但是依然有很多小伙伴处于懵逼的状态.面试时候最担心的就是被问到面向对象相关的内容,自己看过无数的资料,依然对面向对象百思不得其解.到底什么是原型?什么是构造函数?什么是继承...一提到这些概念那真是欲哭无泪.悲愤交加,甚至恨的直咬牙!所以有必要重新再谈一次面向对象.同时我也希望通过这几篇文章让你对面向对象由恨生爱,再到爱恨交加,最后爱得死去活来! 对象 ???各位老铁们应该听过一个词叫"一切皆对象",而"面向对象"

再和“面向对象”谈恋爱 - 继承(五)

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

再和“面向对象”谈恋爱 - 对象相关概念(二)

上一篇文章把对象的概念讲解了一下,这篇文章要重点解释最让大家犯迷糊的一些概念,包括 构造函数 实例 继承 构造函数的属性与方法(私有属性与方法) 实例的属性与方法(共享属性与方法) prototype(原型) __proto__(原型) 构造函数 构造函数依然是个函数,用来生成对象.所有的对象都是由构造函数创建的 对象哪来的?构造函数生的.而普通函数不能生成对象(不孕不育),构造函数可以生成对象(有生育能力).每个对象都会有一个自己对应的构造函数,但是不代表每个构造函数都会生(生成实例),有不会

再和“面向对象”谈恋爱 - class(四)

在上一篇文章里我介绍了一下面向对象编程的概念,在最后终于喜出望外看到了ES6提供了类的概念了.那这个类如何去用,是这篇文章的主题.ES6给我们提供了一个class关键字.这个关键字跟以前的var let const很像,它们都是用做声明的,而class就是用来声明一个类的. 语法 class name [extends]{ //extends是用来继承的,可选参数 //class body }; 注意 class不能重复声明(与let.const一样) 类的本质还是一个构造函数 class Di

面对对象 谈恋爱五大原则浅析!

面向对象编程其实无时无刻不在向我们阐释婚恋观 面向对象编程5大原则,想来跟处对象是一样一样的: 单一职责原则(SRP): 做一个单纯的人,才会有简单<稳稳的幸福-陈奕迅>: 一个类应该仅有一个引起它变化的原因 开放封闭原则(OCP):悟以往之不谏,知来者犹可追: 既开放又封闭,对扩展是开放的,对更改是封闭的! 里氏替换原则(LSP):花心大萝卜才能永远立于不败之地: 子类可以替换父类并且出现在父类能够出现的任何地方,面向接口编程gof 依赖倒置原则(DIP): 谈恋爱经济也要独立呀: 传统的结

《数据结构与面向对象程序设计》第六周学习总结

学号 2019-2020-1 <数据结构与面向对象程序设计>第六周学习总结 教材学习内容总结 多态引用可以在不同时间指向不同类型对象,即运行一致性的方法出现不一致的行为. 使用父类声明的引用变量可以指向子类的对象,接口也可以实现多态 使用try-catch来实现未捕获的异常的处理.可以使得异常被捕获进而不导致程序出现错误退出. 使用try写入可能产生异常的语句,使用catch来编写在捕获异常后继续执行的代码(可以为空). 自定义异常 - throw:抛出异常 - throws:用于方法名的后面

价值观不同的人不适合谈恋爱

今天和男朋友狂吵架,整个人都不好了. 起因很简单,就是我俩一起睡了一会,错过了电影开场时间.在睡之前我提醒了他很多遍“设闹钟了么?没设闹钟我设一下.”他设置了闹钟可是他没起来,而且还关掉了闹钟,导致我俩一起错过了开场.这场电影,从上周二开始我就计划要看看.周三首映人太多没去,周四太忙没去,周五问他要不要去他觉得太晚没去,周六晚上想着可以去看电影了呀他觉得明天白天去更好又没去.今天周日终于可以看电影了,结果就这么错过了,特别生气,早知道这样的话我不如早点自己去看了电影何必等到现在. 延伸出来的话题

工作就像谈恋爱

企业和员工就像男人和女人,试用期就像在谈恋爱,转正了就是领了红本.无论那个阶段,双方都在有原则,又要对为对方着想,况且好人和好人不一定能够过一被子,也有因为爱而离婚,不然也不会有这么高的离婚率.一部分传统的人顾全大局,委屈求全,离婚是毒蛇.另一部分,则打破传统最求自己的幸福.二者都没错,看你站在那个角度了.老婆也好,老公也好,且行且珍惜,离多了好人也不一定好了.谁都不愿意,闹得家庭破碎,毕竟对大家都不爽.婚姻如此工作亦如此,公司及领导多站在员工的角度想想,员工也多为企业想想,建利要相互的信任,别