new.target 是 es6 引入的元属性,用于检测函数是否被 new 调用:被 new 调用时指向当前构造函数,普通调用时为 undefined,箭头函数无自有 new.target;常用于强制 new 调用、区分继承链中实际构造类及实现抽象基类。

new.target 是 ES6 引入的元属性,用于检测函数是否被 new 操作符调用。它在构造函数内部有效,能清晰区分“普通调用”和“构造调用”,是实现安全类封装、防止误用的重要工具。
new.target 的基本行为
在函数体内:
- 若函数被 new 调用(如 new MyClass()),new.target 指向当前构造函数(即该函数本身);
- 若函数被普通调用(如 MyClass()),new.target 为 undefined;
- 箭头函数没有自己的 new.target,会继承外层函数的值(通常为 undefined)。
常见用途:强制必须使用 new
防止用户忘记写 new 导致 this 指向意外(如指向全局对象或 undefined):
function Person(name) {
if (!new.target) {
throw new Error('Person 必须通过 new 调用');
}
this.name = name;
}
这样 Person('Alice') 会报错,而 new Person('Alice') 正常执行。
区分派生类与基类构造函数
在继承链中,new.target 始终指向**实际被 new 的那个类**,而非当前函数定义所在的类。这可用于实现“抽象基类”或差异化初始化:
-
class Animal { constructor() { console.log(new.target === Animal); } }→ 直接new Animal()输出true -
class Dog extends Animal { constructor() { super(); } }→new Dog()中,new.target是Dog,在Animal构造器里输出false
可据此禁止直接实例化基类:class Shape { constructor() { if (new.target === Shape) throw new Error('Shape 是抽象类'); } }
注意边界情况
以下情况需留意:
- 严格模式下,普通函数调用时 new.target 确实为 undefined;非严格模式下也一样,无需额外切换模式。
- 类的 constructor 内部一定有 new.target(不会为 undefined),因为类只能被 new 调用。
- eval 或 Function 构造器创建的函数中,new.target 行为一致,但实践中极少需要在此类动态函数中判断。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











