new.target 是 javascript 中用于检测函数是否被 new 调用的元属性;在构造函数中指向当前类或函数,非 new 调用时为 undefined,可用于防止误调用、支持继承识别和实现灵活构造器。

new.target 是 JavaScript 中用于检测函数是否被 new 关键字调用的元属性。它在构造函数内部有效,能帮助你区分「作为普通函数调用」和「作为构造函数调用」两种场景,避免意外的错误行为。
new.target 的基本行为
在函数体内,new.target 指向当前被 new 调用的构造函数本身;如果没用 new 调用,则 new.target 为 undefined。
- 类(class)方法中,
new.target在构造器(constructor)里指向该类,在普通方法里为undefined(除非该方法也被new调用,但通常不会) - 普通函数(包括箭头函数)中,
new.target在非构造调用时为undefined;若用new调用一个普通函数,它就指向该函数 - 箭头函数没有自己的
new.target,会沿作用域链向上查找,通常得到外层函数的new.target或undefined
防止非 new 调用构造函数
这是最常见用途:确保某个函数只能通过 new 调用,否则抛错。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function Person(name) {
if (!new.target) {
throw new Error('Person 必须用 new 调用');
}
this.name = name;
}
// ✅ 正确
const p1 = new Person('Alice');
// ❌ 报错:Person 必须用 new 调用
// const p2 = Person('Bob');
支持继承时识别实际构造者
在父类构造器中,new.target 指向**实际被 new 的子类**,而非父类本身。这可用于实现「基于调用者类型差异化初始化」。
class Animal {
constructor() {
console.log('new.target:', new.target.name); // 输出子类名,如 'Dog'
if (new.target === Animal) {
throw new Error('Animal 是抽象类,不能直接实例化');
}
}
}
class Dog extends Animal {
constructor() {
super();
}
}
new Dog(); // new.target 是 Dog
// new Animal(); // 报错
与 class 和工厂函数结合的实用技巧
你可以用 new.target 实现「既支持 new 又支持普通调用」的灵活构造器:
- 若
new.target存在,按构造函数逻辑返回新实例 - 若不存在,自动补上
new并返回实例(模拟“ forgiving constructor”)
function Vector(x, y) {
if (!new.target) {
return new Vector(x, y); // 自动补 new
}
this.x = x;
this.y = y;
}
// 两种写法都有效
const v1 = new Vector(1, 2);
const v2 = Vector(3, 4); // 内部自动 new
不复杂但容易忽略。合理使用 new.target 能让构造逻辑更健壮、更可控。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










