new.target 是 JavaScript 中唯一能精确标识本次 new 表达式左侧实际构造器的只读元属性,严格等于字面调用的构造函数,不可篡改,且在继承、代理、装饰等场景下始终指向物理源头。

new.target 是 JavaScript 中用于检测函数是否被 new 调用的关键元属性,但它本身并不直接“锁定物理构造器”——真正能精确识别当前执行上下文中的**实际构造器(即 new 时左侧的那个函数)**的,正是 new.target 的值本身。
new.target 就是真正的物理构造器
当一个函数通过 new Foo() 调用时,new.target 在该函数内部**严格等于 Foo**(即字面调用的那个构造器),而非其原型链上的父类或代理包装器。这是它最核心、最可靠的语义:
- 在普通函数中,
new.target为undefined(未被new调用) - 在类或构造函数中,
new.target指向**本次new表达式左侧的构造器**,哪怕它被继承、被代理、被装饰 - 它不会被
Reflect.construct或子类重写覆盖 —— 子类中new.target仍是子类自身,不是父类
区分直接构造 vs 继承调用
子类构造器中常需判断:这次 new 是直接对本类调用,还是通过子类调用?new.target 可直接比对:
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
class A { constructor() { console.log(new.target === A); } }
class B extends A { constructor() { super(); } }
new A(); // true
new B(); // false(new.target 是 B,不等于 A)
这使得你能在基类中做“仅限顶层实例化”的校验,或按构造器身份分支逻辑。
防御代理/装饰器篡改构造意图
即使构造器被 Proxy 包裹,只要最终是 new proxy() 形式调用,new.target 仍指向原始目标函数(非 Proxy 对象):
- Proxy 的
constructtrap 中,newTarget参数就是真实构造器 - 这意味着无法靠包装隐藏“谁被真正 new 了”——
new.target始终暴露物理源头 - 可用于白名单校验:只允许特定构造器被实例化,拒绝代理或匿名包装调用
与 this.constructor 的关键区别
this.constructor 可被显式修改(如赋值 this.constructor = null 或原型篡改),而 new.target 是只读、不可赋值、不可屏蔽的运行时元信息:
-
this.constructor是实例身上的属性,依赖原型链和可变状态 -
new.target是执行上下文固有属性,由 JS 引擎在进入函数时静态绑定 - 因此,需要**绝对可信的构造器标识时,必须用
new.target,而非this.constructor**

















