在 ES12 中,我们可以使用 new.target
属性来获取构造函数的实例化信息。这个属性可以让我们更好地处理类的继承和多态,同时也可以用来判断一个函数是否被作为构造函数调用。
new.target 是什么?
new.target
是一个在构造函数内部可用的特殊变量,它会在构造函数被实例化时被赋值。如果构造函数是通过 new
关键字调用的,则 new.target
的值会是这个构造函数本身;否则,new.target
的值会是 undefined
。
使用 new.target 判断函数是否被作为构造函数调用
我们可以使用 new.target
来判断一个函数是否被作为构造函数调用。例如,我们可以定义一个函数 MyClass
,并在其中使用 new.target
来判断该函数是否被作为构造函数调用:
function MyClass() { if (!new.target) { throw new Error('MyClass must be called with new'); } console.log('MyClass instantiated with new'); } const myInstance = new MyClass(); // logs "MyClass instantiated with new" const myInstance2 = MyClass(); // throws an error
在这个例子中,我们首先判断 new.target
的值是否为 undefined
。如果是,说明该函数没有被作为构造函数调用,我们就可以抛出一个错误。如果 new.target
的值是构造函数本身,说明该函数是通过 new
关键字调用的,我们就可以继续执行后续操作。
使用 new.target 处理类的继承和多态
new.target
还可以用来处理类的继承和多态。例如,我们可以定义一个基类 Animal
和一个继承自 Animal
的子类 Cat
,并在其中使用 new.target
来判断实例化的对象是哪个类的实例。
class Animal { constructor() { console.log('Animal instantiated with', new.target.name); } } class Cat extends Animal { constructor() { super(); console.log('Cat instantiated with', new.target.name); } } const animal = new Animal(); // logs "Animal instantiated with Animal" const cat = new Cat(); // logs "Animal instantiated with Cat" and "Cat instantiated with Cat" const cat2 = new Animal(); // logs "Animal instantiated with Animal"
在这个例子中,我们首先定义了一个基类 Animal
,它有一个构造函数,并在其中使用 new.target
来输出实例化时的类名。接着,我们定义了一个继承自 Animal
的子类 Cat
,并在其中使用 super()
调用父类的构造函数,然后再次使用 new.target
来输出实例化时的类名。
通过这种方式,我们可以在子类中使用 new.target
来获取实例化时的类名,从而实现类的多态。
总结
ES12 中的 new.target
属性可以让我们更好地处理类的继承和多态,同时也可以用来判断一个函数是否被作为构造函数调用。在实际开发中,我们可以根据需要使用 new.target
来实现更加灵活和高效的代码编写。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65bee585add4f0e0ff86b388