元属性new.target
在es5中,通常判断一个对象是否是一个类的实例的时候使用instanceof
关键字,例如如下代码
function Person(name) {
if (this instanceof Person) {
this.name = name
} else {
throw new Error('必须使用new关键字来调用Person')
}
}
当判断this
不是Person
类的实例的时候,将会抛出一个异常。
但是如下通过call
或apply
修改this
绑定作用域,那么在Person
类中是无法区分到底是通过Person.call()
或Person.apply()
还是new
关键字调用得到的Person
实例。
所以,如下代码也能够正常执行:
let person = new Person('Leevare')
let anotherPerson = Person.call(person, 'Jason')
在es6中引入了new.target
这个元属性。当通过new
的方式调用时,new.target
将会被赋予新创建的对象实例,此处则为Person
,其它方式将会为undefined
。所以可以将上述的代码修改为如下:
function Person(name) {
if(new.target !== Person) {
throw new Error('必须使用new关键字来调用Person')
}else {
this.name = name
}
}
此时,若使用call
或apply
则会抛出异常。
利用new.target
的这一特性,可以实现一个只能被继承,而不能被实例化的类。
class Parent {
constructor() {
if (new.target === Parent) {
throw new Error('Parent不能被实例化')
}
}
}
class Child extends Parent {
constructor(a, b) {
super()
}
}
const child = new Child(1, 2)
const parent = new Parent() //报错
如果您觉得本文对您有用,欢迎捐赠或留言~
- 本博客所有文章除特别声明外,均可转载和分享,转载请注明出处!
- 本文地址:https://www.leevii.com/?p=1157