new 是構造函數生成實例的命令, ES6為 new 命令引入了 new.target屬性。這個屬性用於確定構造函數是怎麼調用的。 在構造函數中, 如果一個構造函數 操作符調用的, 會返回 undefined。 使用場景 如果一個構造函數不通過 new 命令生成實例, 就報錯提醒 es5中是這樣做的 ...
new 是構造函數生成實例的命令, ES6為 new 命令引入了 new.target屬性。這個屬性用於確定構造函數是怎麼調用的。
在構造函數中, 如果一個構造函數不是通過 new
操作符調用的, new.target
會返回 undefined。
使用場景
如果一個構造函數不通過 new 命令生成實例, 就報錯提醒
es5中是這樣做的:
function Shape(options) {
if (this instanceof Shape) {
this.options = options
} else {
// 要麼手動給它創建一個實例並返回
// return new Shape(options)
// 要麼提醒
throw new Error('Shape 構造函數必須使用 new 操作符')
}
}
es6中可以這樣做:
function Shape(options) {
// if (new.target !== 'undefined') {} 必須要在 constructor中使用 new.target, 在這裡判斷會報錯
constructor(options) {
if (new.target !== 'undefined') {
this.options = options
} else {
throw new Error('必須使用 new 操作符')
}
}
}
以上代碼通過 new.target 屬性判斷返回的是不是undefined即可知道這個構造函數是不是通過 new 操作符調用
一個構造函數只能用於子類繼承, 自身不能 new
new.target這個屬性,當子類繼承父類會返回子類的構造函數名稱
class Parent {
constructor() {
console.log(new.target)
}
}
class Child extends Parent {
constructor() {
super()
}
}
// Child
以上代碼 Child子類繼承父類, 那麼父類構造函數中的 new.target 是子類構造函數的名稱。
規定構造函數只能用於繼承
class Zoo {
constructor() {
if (new.target === Zoo) throw new Error('Zoo構造函數只能用於子類繼承')
}
}
const zoo = new Zoo() // 報錯
class Dog extends Zoo {
constructor() {
super()
}
}
const dog = new Dog() // 不報錯
tip : new.target 在外部使用會報錯