2021.05.25(new.target 属性)

new.target 属性

new  是从构造函数生成实例对象的命令。ES6 为 new  命令引入了一个 new.target  属性,该属
性一般用在构造函数之中,返回 new  命令作用于的那个构造函数。如果构造函数不是通过 new  命
令或 Reflect.construct()  调用的, new.target  会返回 undefined  ,因此这个属性可以用来
确定构造函数是怎么调用的。

1.  function Person(name) {
2.  if (new.target !== undefined) {
3.  this.name = name;
4.  } else {
5.  throw new Error('必须使用 new 命令生成实例');
6.  }
7.  }
8.
9.  // 另一种写法
10.  function Person(name) {
11.  if (new.target === Person) {
12.  this.name = name;
13.  } else {
14.  throw new Error('必须使用 new 命令生成实例');
15.  }
16.  }
17.
18.  var person = new Person('张三'); // 正确
19.  var notAPerson = Person.call(person, '张三'); // 报错

上面代码确保构造函数只能通过 new  命令调用。
Class 内部调用 new.target  ,返回当前 Class。

1.  class Rectangle {
2.  constructor(length, width) {
3.  console.log(new.target === Rectangle);
4.  this.length = length;
5.  this.width = width;
6.  }
7.  }
8.
9.  var obj = new Rectangle(3, 4); // 输出 true

需要注意的是,子类继承父类时, new.target  会返回子类。

1.  class Rectangle {
2.  constructor(length, width) {
3.  console.log(new.target === Rectangle);
4.  // ...
5.  }
6.  }
7.
8.  class Square extends Rectangle {
9.  constructor(length, width) {
10.  super(length, width);
11.  }
12.  }
13.
14.  var obj = new Square(3); // 输出 false

上面代码中, new.target  会返回子类。

利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。

1.  class Shape {
2.  constructor() {
3.  if (new.target === Shape) {
4.  throw new Error('本类不能实例化');
5.  }
6.  }
7.  }
8.
9.  class Rectangle extends Shape {
10.  constructor(length, width) {
11.  super();
12.  // ...
13.  }
14.  }
15.
16.  var x = new Shape(); // 报错
17.  var y = new Rectangle(3, 4); // 正确

上面代码中, Shape  类不能被实例化,只能用于继承。
注意,在函数外部,使用 new.target  会报错。

 

2021-05-25 17:51:01

posted @ 2021-05-25 17:51  铁打的代码流水的bug  阅读(81)  评论(0)    收藏  举报