ES6 new.target和super

130 阅读1分钟

new.target和super

new.target

new.target返回使用new方法调用类时的类的名称,子类继承父类时,new.target会返回子类

1、super

(1) 函数

在子类继承父类中,super作为函数调用,只能写在子类的构造函数(constructor)里面,super代表的是父类的构造函数

class A {
  constructor() {
    console.log(new.target.name);
  }
}
class B extends A {
  constructor() {
    super();//这里的super相当于A类的constructor构造函数,会执行A的constructor,但是此时的this指 
            //向的是B,所以打印出B
            //换一种方法理解是:在执行super时,A把constructor方法给了B,此时B有了A的功能,但是执 
            //行的是B的内容,也就是es5的A.prototype.constructor.call(this)。
  }
}
new A() // A
new B() // B

(2)对象

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

1、普通方法

class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();

注意:由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的

2、静态方法中

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

2、new.target

写出只能被继承使用的类 , 限制制类的调用方法,判断new.target是不是未定义

class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('本类不能实例化');
    }
  }
}
class Rectangle extends Shape {
  constructor(length, width) {
    super();
    // ...
  }
}
var x = new Shape();  // 报错
var y = new Rectangle(3, 4);  // 正确

参考: