javascript new.target的学习笔记

 更新时间:2025年08月01日 08:29:01   作者:明长歌  
new.target是一个元属性(meta property),在ECMAScript 2015 (ES6) 中引入,用于检测函数是否通过new关键字调用,下面就来具体介绍一下javascript new.target,感兴趣的可以了解一下

new.target

new.target 是一个元属性(meta property),在ECMAScript 2015 (ES6) 中引入,用于检测函数是否通过 new 关键字调用。简单来说,当一个函数用 new 关键字调用时,new.target 会指向这个函数本身;如果函数是直接调用,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 保证是一个可构造的函数值或 undefined。

在类构造函数中,它指向 new 调用的类,这可能是当前构造函数的子类,因为子类通过 super() 传递调用了父类的构造函数。

在父类的构造函数里,new.target 并不等于父类本身,而是“真正被 new 的那个类”——往往正是它的某个子类。因为子类在构造时要先 super(),于是父类构造函数的 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

在普通函数中,如果函数是直接通过 new 构造的,则 new.target 指向函数本身。如果函数不是通过 new 调用的,则 new.targetundefined。函数可以被用作 extends 的基类,这种情况下 new.target 可能指向子类。

function Foo(msg) {
    console.log(msg, '--new.target =', new.target);
}
// 通过 `new` 构造的,则 `new.target` 指向函数本身
new Foo('new Foo');
/* 输出:new Foo --new.target = ƒ Foo(msg) {
    console.log(msg, '--new.target =', new.target);
} */
// 不是通过 `new` 调用的,则 `new.target` 是 `undefined`
Foo('call Foo');  
/* 输出:call Foo --new.target = undefined */

// 函数可以被用作 `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');
    }
}  */     

如果构造函数(类或者函数)是通过 Reflect.construct() 调用的,那么 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

在箭头函数中,new.target 是从周围的作用域继承的。如果箭头函数不是在另一个具有 new.target 绑定的类或函数中定义的,则会抛出语法错误。

class A {
    constructor() {
        const arrow = () => console.log('new.target →', new.target);
        arrow();          // 箭头函数继承自构造函数作用域
    }
}
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

在静态初始化块中,new.targetundefined

class WithStatic {
   static {
        console.log('Static block new.target:', new.target); // undefined
    }
}
new WithStatic();
// 输出:Static block new.target: undefined

参考:

MDN new.target

到此这篇关于javascript new.target的学习笔记的文章就介绍到这了,更多相关javascript new.target内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript中的 object 和 function小结

    javascript中的 object 和 function小结

    JavaScript的面向对象是基于原形的,所有对象都有一条属于自己的原型链。Object与Function可能很多看Object instanceof Function , Function instanceof Object都为true而迷惑,所以首先看下对象的实例。
    2016-08-08
  • webpack中splitChunks分包策略的实现

    webpack中splitChunks分包策略的实现

    splitChunks是 webpack 中用于分包的配置选项之一,本文主要介绍了webpack中splitChunks分包策略的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • js 递归json树实现根据子id查父id的方法分析

    js 递归json树实现根据子id查父id的方法分析

    这篇文章主要介绍了js 递归json树实现根据子id查父id的方法,结合实例形式分析了JavaScript递归遍历json进行数据查询的相关操作技巧,需要的朋友可以参考下
    2019-11-11
  • 在webview中如何跳回小程序步骤详解

    在webview中如何跳回小程序步骤详解

    这篇文章主要介绍了在微信小程序中使用web-view组件嵌入网页并实现从网页跳回到小程序的步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-01-01
  • js如何修改对象数组的key值

    js如何修改对象数组的key值

    这篇文章主要介绍了js如何修改对象数组的key值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • Django模板继承 extend标签实例代码详解

    Django模板继承 extend标签实例代码详解

    这篇文章主要介绍了Django模板继承 extend标签实例代码,非常不错,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • javascript iframe跨域详解

    javascript iframe跨域详解

    这篇文章主要介绍了javascript iframe跨域详解的相关资料,需要的朋友可以参考下
    2016-10-10
  • 微信小程序海报绘制示例讲解

    微信小程序海报绘制示例讲解

    这篇文章主要介绍了微信小程序海报绘制示例,海报分享功能在许多应用中应该是很常见的,因为它作为一种常用的应用推广和拉新的方式,下面我们来通过案例学习如何绘制
    2024-05-05
  • js在输入框屏蔽按键,只能键入数字的示例代码

    js在输入框屏蔽按键,只能键入数字的示例代码

    本篇文章主要介绍了js在输入框屏蔽按键,只能键入数字的示例代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • JavaScript对象与JSON格式的转换及JSON.stringify和JSON.parse的使用方法

    JavaScript对象与JSON格式的转换及JSON.stringify和JSON.parse的使用方法

    这篇文章主要介绍了JavaScript对象与JSON格式的转换及JSON.stringify和JSON.parse的使用方法,JSON是JavaScript表达值和对象的通用数据格式,其本质就是符合一定规范的字符串
    2022-07-07

最新评论