javascript?new.target的學(xué)習(xí)筆記
new.target
new.target 是一個(gè)元屬性(meta property),在ECMAScript 2015 (ES6) 中引入,用于檢測函數(shù)是否通過 new 關(guān)鍵字調(diào)用。簡單來說,當(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中的 object 和 function小結(jié)
JavaScript的面向?qū)ο笫腔谠蔚?,所有?duì)象都有一條屬于自己的原型鏈。Object與Function可能很多看Object instanceof Function , Function instanceof Object都為true而迷惑,所以首先看下對(duì)象的實(shí)例。2016-08-08
webpack中splitChunks分包策略的實(shí)現(xiàn)
splitChunks是 webpack 中用于分包的配置選項(xiàng)之一,本文主要介紹了webpack中splitChunks分包策略的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-06-06
js 遞歸json樹實(shí)現(xiàn)根據(jù)子id查父id的方法分析
這篇文章主要介紹了js 遞歸json樹實(shí)現(xiàn)根據(jù)子id查父id的方法,結(jié)合實(shí)例形式分析了JavaScript遞歸遍歷json進(jìn)行數(shù)據(jù)查詢的相關(guān)操作技巧,需要的朋友可以參考下2019-11-11
Django模板繼承 extend標(biāo)簽實(shí)例代碼詳解
這篇文章主要介紹了Django模板繼承 extend標(biāo)簽實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05
JavaScript對(duì)象與JSON格式的轉(zhuǎn)換及JSON.stringify和JSON.parse的使用方法
這篇文章主要介紹了JavaScript對(duì)象與JSON格式的轉(zhuǎn)換及JSON.stringify和JSON.parse的使用方法,JSON是JavaScript表達(dá)值和對(duì)象的通用數(shù)據(jù)格式,其本質(zhì)就是符合一定規(guī)范的字符串2022-07-07

