• ES6中类Class的super关键字


    super 关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

    1、super当做函数使用

    super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super() 函数。注意:作为函数时,super() 只能用在子类的构造函数之中,用在其他地方就会报错。

    class A {}
    class B extends A { constructor() { super(); } }

    super 作为函数调用时,内部的 this 指的是子类实例

    class A {
      constructor() {
        this.show();
      }
    }
    class B extends A {
      constructor() {
        super();
      }
      show(){
        console.log('实例');
      }
      static show(){
        console.log('子类');
      }
    }
    new B()  //输出 '实例' ,new B 时触发了 B 的构造函数,所以触发了 super 方法,即触发了父类 A 的构造函数,此时的 this.show 的 this 指的是子类 

    2、super 作为对象使用

    super 作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

    2.1、super在普通方法中(即非静态方法)及此时的 this 关键字指向

    class A {
      p() {
        return 2;
      }
    }
    class B extends A {
      constructor() {
        super();
        console.log(super.p()); // 2  此时的super指向父类原型对象,即 A.prototype
      }
    }
    let b = new B();  //2

    由于在普通方法中的 super 指向父类的原型对象,所以如果父类上的方法或属性是定义在实例上的,就无法通过 super 调用的。如下所示:

    class A {
      constructor() {  //在构造函数上定义的属性和方法相当于定义在父类实例上的,而不是原型对象上
        this.p = 2;
      }
    }
    class B extends A {
      get m() {
        return super.p;
      }
    }
    
    let b = new B();
    console.log(b.m) // undefined

    在子类普通方法中通过 super 调用父类的方法时,方法内部的 this 指向的是当前的子类实例。

    class A {
      constructor() {
        this.x = 1;
      }
      print() {
        console.log(this.x);
      }
    }
    class B extends A {
      constructor() {
        super();
        this.x = 2;
       super.y = 123;  //如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
      }
      m() {
        super.print();
      }
    }
    let b
    = new B(); b.m() // 2 console.log(b.y); //123

    2.2、super在静态方法中及此时的 this 关键字指向

    super作为对象,用在静态方法之中,这时 super 将直接指向父类,而不是父类的原型对象。

    class Parent {
      static myMethod(msg) {
        console.log('static', msg);
      }
      myMethod(msg) {
        console.log('instance', msg);
      }
    }
    class Child extends Parent {
      static myMethod(msg) {
        super.myMethod(msg);
      }
      myMethod(msg) {
        super.myMethod(msg);
      }
    }
    Child.myMethod(1); // static 1
    var child = new Child();
    child.myMethod(2); // instance 2

    在子类的静态方法中通过 super 调用父类的方法时,方法内部的 this 指向当前的子类,而不是子类的实例。

    class A {
      constructor() {
        this.x = 1;
      }
      static print() {
        console.log(this.x);
      }
    }
    class B extends A {
      constructor() {
        super();
        this.x = 2;
      }
      static m() {
        super.print();
      }
    }
    B.x = 3;
    B.m() // 3
  • 相关阅读:
    ROS_Kinetic_08 ROS的集成开发环境(IDEs)之使用Eclipse
    如何写好一份竞品运营分析报告?
    我眼中的Linux设备树(六 memory&chosen节点)
    【干货】前端开发者最常用的六款IDE
    【前端图表】echarts散点图鼠标划过散点显示信息
    【前端图表】echarts实现散点图x轴时间轴
    三分钟教你学会如何将密文解码成明文
    2018上半年GitHub上最热门的开源项目
    进阶攻略|前端完整的学习路线
    进阶攻略|前端最全的框架总结
  • 原文地址:https://www.cnblogs.com/wenxuehai/p/10361653.html
Copyright © 2020-2023  润新知