javascript?new.target的學(xué)習(xí)筆記
new.target
new.target 是一個(gè)元屬性(meta property),在ECMAScript 2015 (ES6) 中引入,用于檢測(cè)函數(shù)是否通過 new 關(guān)鍵字調(diào)用。簡(jiǎn)單來說,當(dāng)一個(gè)函數(shù)用 new 關(guān)鍵字調(diào)用時(shí),new.target 會(huì)指向這個(gè)函數(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è)可構(gòu)造的函數(shù)值或 undefined。
在類構(gòu)造函數(shù)中,它指向 new 調(diào)用的類,這可能是當(dāng)前構(gòu)造函數(shù)的子類,因?yàn)樽宇愅ㄟ^ super() 傳遞調(diào)用了父類的構(gòu)造函數(shù)。
在父類的構(gòu)造函數(shù)里,new.target 并不等于父類本身,而是“真正被 new 的那個(gè)類”——往往正是它的某個(gè)子類。因?yàn)樽宇愒跇?gòu)造時(shí)要先 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 傳遞的值(默認(rèn)為 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ù)不是在另一個(gè)具有 new.target 綁定的類或函數(shù)中定義的,則會(huì)拋出語法錯(cuò)誤。
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); // 報(bào)錯(cuò):ReferenceError
};
arrow();
//輸出報(bào)錯(cuò):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的學(xué)習(xí)筆記的文章就介紹到這了,更多相關(guān)javascript new.target內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript函數(shù)綁定用法實(shí)例分析
這篇文章主要介紹了JavaScript函數(shù)綁定用法,結(jié)合實(shí)例形式分析了javascript函數(shù)綁定的原理、實(shí)現(xiàn)方法與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
UniApp?WebView頁面中的請(qǐng)求跨域問題解決
在使用UniApp開發(fā)中,通過WebView組件加載本地網(wǎng)頁時(shí),往往會(huì)遇到跨域問題,下面這篇文章主要介紹了UniApp?WebView頁面中的請(qǐng)求跨域問題解決的相關(guān)資料,需要的朋友可以參考下2024-10-10
js?實(shí)現(xiàn)picker?選擇器示例詳解
這篇文章主要為大家介紹了js?實(shí)現(xiàn)picker?選擇器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
原生JavaScript和Vue實(shí)現(xiàn)從百度地圖抓取經(jīng)緯度
在前端開發(fā)中,使用百度地圖 API 來獲取用戶的經(jīng)緯度是一種常見需求,本文提供了使用原生 JavaScript 和 Vue.js 實(shí)現(xiàn)從百度地圖抓取經(jīng)緯度的詳細(xì)示例,需要的可以了解下2024-11-11
關(guān)于在IE下的一個(gè)安全BUG --可用于跟蹤用戶的系統(tǒng)鼠標(biāo)位置
本篇文章小編將為大家介紹,關(guān)于在IE下的一個(gè)安全BUG --可用于跟蹤用戶的系統(tǒng)鼠標(biāo)位置。需要的朋友可以參考一下2013-04-04
原生javascript實(shí)現(xiàn)圖片輪播切換效果
這篇文章主要為大家詳細(xì)介紹了原生javascript實(shí)現(xiàn)圖片輪播切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
Javascript中的方法鏈(Method Chaining)介紹
這篇文章主要介紹了Javascript中的方法鏈(Method Chaining)介紹,本文講解了Javascript Method Chaining、Method Chaining 使用、Method Chaining VS prototype Chaining等內(nèi)容,需要的朋友可以參考下2015-03-03

