javascript?new.target的學習筆記
new.target
new.target 是一個元屬性(meta property),在ECMAScript 2015 (ES6) 中引入,用于檢測函數(shù)是否通過 new 關(guān)鍵字調(diào)用。簡單來說,當一個函數(shù)用 new 關(guān)鍵字調(diào)用時,new.target 會指向這個函數(shù)本身;如果函數(shù)是直接調(diào)用,new.target 的值則為 undefined。
function Foo() {
console.log('new.target',new.target)
console.log('new.target.prototype',new.target.prototype)
if (!new.target) {
throw new TypeError("calling Foo constructor without new is invalid");
}
}
try {
new Foo();
Foo();
} catch (e) {
console.log(e);
// Expected output: TypeError: calling Foo constructor without new is invalid
}
// 輸出:
/*
"new.target" function Foo() {
console.log('new.target',new.target)
console.log('new.target.prototype',new.target.prototype)
if (!new.target) {
throw new TypeError("calling Foo constructor without new is invalid");
}
}
"new.target.prototype" Object { }
*/
/*
"new.target" undefined
TypeError: Cannot read properties of undefined (reading 'prototype')
*/
值
new.target 保證是一個可構(gòu)造的函數(shù)值或 undefined。
在類構(gòu)造函數(shù)中,它指向 new 調(diào)用的類,這可能是當前構(gòu)造函數(shù)的子類,因為子類通過 super() 傳遞調(diào)用了父類的構(gòu)造函數(shù)。
在父類的構(gòu)造函數(shù)里,new.target 并不等于父類本身,而是“真正被 new 的那個類”——往往正是它的某個子類。因為子類在構(gòu)造時要先 super(),于是父類構(gòu)造函數(shù)的 new.target 就指向了子類。
class Animal{
constructor() {
console.log('Animal -> new.target.name:', new.target.name);
}
}
class Dog extends Animal{
constructor() {
super();
console.log('Dog -> new.target.name:', new.target.name);
}
}
class toyDog extends Dog{
constructor() {
super();
console.log('ToyDog -> new.target.name:', new.target.name);
}
}
new Dog();
// Animal -> new.target.name: Dog
// Dog -> new.target.name: Dog
console.log('----------------');
new toyDog();
// Animal -> new.target.name: toyDog
// Dog -> new.target.name: toyDog
// ToyDog -> new.target.name: toyDog
在普通函數(shù)中,如果函數(shù)是直接通過 new 構(gòu)造的,則 new.target 指向函數(shù)本身。如果函數(shù)不是通過 new 調(diào)用的,則 new.target 是 undefined。函數(shù)可以被用作 extends 的基類,這種情況下 new.target 可能指向子類。
function Foo(msg) {
console.log(msg, '--new.target =', new.target);
}
// 通過 `new` 構(gòu)造的,則 `new.target` 指向函數(shù)本身
new Foo('new Foo');
/* 輸出:new Foo --new.target = ? Foo(msg) {
console.log(msg, '--new.target =', new.target);
} */
// 不是通過 `new` 調(diào)用的,則 `new.target` 是 `undefined`
Foo('call Foo');
/* 輸出:call Foo --new.target = undefined */
// 函數(shù)可以被用作 `extends` 的基類,這種情況下 `new.target` 可能指向子類。
class Bar extends Foo {
constructor() {
super('new Bar');
}
}
new Bar();
/* 輸出:new Bar --new.target = class Bar extends Foo {
constructor() {
super('new Bar');
}
} */
如果構(gòu)造函數(shù)(類或者函數(shù))是通過 Reflect.construct() 調(diào)用的,那么 new.target 指向作為 newTarget 傳遞的值(默認為 target)。
function One(name) {
this.name = name;
console.log('One -> new.target.name:', new.target.name);
}
const obj=Reflect.construct(One, ['aa'], Array);
console.log(obj); // 輸出:Array {name: 'aa'}
console.log('obj instanceof One:', obj instanceof One); // 輸出:obj instanceof One: false
console.log('obj instanceof Array:', obj instanceof Array); // 輸出:obj instanceof Array: true
在箭頭函數(shù)中,new.target 是從周圍的作用域繼承的。如果箭頭函數(shù)不是在另一個具有 new.target 綁定的類或函數(shù)中定義的,則會拋出語法錯誤。
class A {
constructor() {
const arrow = () => console.log('new.target →', new.target);
arrow(); // 箭頭函數(shù)繼承自構(gòu)造函數(shù)作用域
}
}
class B extends A {}
new B();
//輸出:new.target → class B extends A {}
// 在全局作用域里
const arrow = () => {
console.log(new.target); // 報錯:ReferenceError
};
arrow();
//輸出報錯:Uncaught SyntaxError: new.target expression is not allowed here
在靜態(tài)初始化塊中,new.target 是 undefined
class WithStatic {
static {
console.log('Static block new.target:', new.target); // undefined
}
}
new WithStatic();
// 輸出:Static block new.target: undefined
參考:
到此這篇關(guān)于javascript new.target的學習筆記的文章就介紹到這了,更多相關(guān)javascript new.target內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生JavaScript和Vue實現(xiàn)從百度地圖抓取經(jīng)緯度
在前端開發(fā)中,使用百度地圖 API 來獲取用戶的經(jīng)緯度是一種常見需求,本文提供了使用原生 JavaScript 和 Vue.js 實現(xiàn)從百度地圖抓取經(jīng)緯度的詳細示例,需要的可以了解下2024-11-11
關(guān)于在IE下的一個安全BUG --可用于跟蹤用戶的系統(tǒng)鼠標位置
本篇文章小編將為大家介紹,關(guān)于在IE下的一個安全BUG --可用于跟蹤用戶的系統(tǒng)鼠標位置。需要的朋友可以參考一下2013-04-04
Javascript中的方法鏈(Method Chaining)介紹
這篇文章主要介紹了Javascript中的方法鏈(Method Chaining)介紹,本文講解了Javascript Method Chaining、Method Chaining 使用、Method Chaining VS prototype Chaining等內(nèi)容,需要的朋友可以參考下2015-03-03

