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

浙公网安备 33010602011771号