ES12 增加了 new.target 属性,可以让开发者在类构造函数中获取实例的构造函数。在本篇文章中,我们将详细介绍 new.target 的使用方法,以及它在前端开发中的指导意义。
new.target 简介
new.target 属性在 ES6 中首次出现。它是一个元属性,能够在构造函数中获取 new 操作符的目标构造函数。举个例子:
// javascriptcn.com 代码示例 class Animal { constructor() { console.log(new.target); } } class Dog extends Animal { constructor() { super(); } } new Animal(); // Animal new Dog(); // Dog
在 Animal 的构造函数中,new.target 的值是 Animal。在 Dog 的构造函数中,new.target 的值是 Dog。我们可以利用这个特性做很多有用的事情,例如:
- 检查构造函数的调用方式是否符合预期。
- 在类继承链中,获取正确的父类构造函数。
使用案例
我们可以使用 new.target 属性来校验构造函数调用方式,例如:
// javascriptcn.com 代码示例 class Singleton { constructor() { if (new.target === Singleton) { throw new Error('Singleton cannot be initialized directly.'); } } } class Database extends Singleton { constructor() { super(); } }
在这个例子中,我们判断了 new.target 是否等于 Singleton。如果是,说明当前是直接对 Singleton 进行实例化操作,这是不被允许的。如果不是,说明当前是对继承 Singleton 的子类进行实例化操作,这是被允许的。
我们还可以利用 new.target 扩展出更灵活的类,例如:
// javascriptcn.com 代码示例 function withUniqueId(BaseClass) { return class extends BaseClass { constructor(...args) { super(...args); this.id = Math.random().toString(36).substring(2,15); } } } class Person { constructor(name) { this.name = name; } } class Employee extends withUniqueId(Person) { constructor(name, position) { super(name); this.position = position; } } const employee = new Employee('John', 'Developer'); console.log(employee.id); // a2ma14avy32fx
在这个例子中,我们定义了一个 withUniqueId 装饰器函数,它能够为传入的类添加一个 id 属性。该装饰器函数使用了 new.target,确保返回的类也支持 new 操作符。
指导意义
new.target 的出现为我们提供了更多的灵活性,并简化了一些设计模式的实现,例如工厂模式。在实际开发中,我们可以根据实际需求使用 new.target 属性,例如:
- 校验构造函数的调用方式是否符合预期。
- 扩展类的功能以满足不同的需求。
- 根据子类的类型返回不同的实例。
总结一下,new.target 的使用让我们的开发更加符合面向对象编程的思想,可以让代码更加简洁、灵活。当然,也要注意新特性的兼容性和使用时的细节。
示例代码
// javascriptcn.com 代码示例 class Animal { constructor() { console.log(new.target); } } class Dog extends Animal { constructor() { super(); } } new Animal(); // Animal new Dog(); // Dog
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/654854d87d4982a6eb29b485