构造函数可加 new.target 检测调用方式:若未用 new,则自动补 new 调用;严格模式下 this 为 undefined,instanceof 会报错,故需先判 this 是否为对象;class 构造器强制 require new,无法兜底。

如果构造函数被直接调用(没加 new),this 会指向全局对象(浏览器中是 window,Node.js 中是 global),容易污染全局、返回 undefined 或引发隐晦 bug。可以通过在函数内部检测 this 是否为当前构造函数的实例来安全兜底——若不是,就自动补上 new 调用。
用 instanceof 检测 this 是否为正确实例
在构造函数开头判断 this 是否已经是该函数的实例,如果不是,就手动用 new 重新调用并返回结果:
function Person(name) {
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
<p>// 两种调用都安全
const a = Person('Alice'); // 自动补 new,返回 Person 实例
const b = new Person('Bob'); // 正常调用
console.log(a.name, b.name); // 'Alice' 'Bob'
</p>
兼容箭头函数和严格模式下的 this 绑定
严格模式下,普通函数不加 new 调用时 this 是 undefined,此时 instanceof 会报错(因为不能对 undefined 做 instanceof 判断)。稳妥做法是先检查 this 是否为对象(且不为 null):
- 用
Object.prototype.toString.call(this) === '[object Object]'或更简洁的this && typeof this === 'object' - 再结合
this.constructor === Person或this instanceof Person进一步确认
综合写法示例:
function Person(name) {
if (!this || !(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
用 new.target 更语义化地检测调用方式
new.target 是 ES6 引入的元属性:在通过 new 调用时指向构造函数本身,直接调用时为 undefined。它不依赖 this 状态,更可靠、更清晰:
function Person(name) {
if (!new.target) {
return new Person(name);
}
this.name = name;
}
注意:new.target 在普通函数(非类或构造函数)中也可用,但需确保运行环境支持(现代浏览器和 Node.js ≥ 6.0 均支持)。
类(class)天然规避该问题,但不可直接兜底
ES6 class 构造器必须用 new 调用,否则直接抛出 TypeError: Class constructor Person cannot be invoked without 'new'。它内部已强制校验,无需手动兜底。但这也意味着你无法像函数那样“优雅降级”——想兼容无 new 调用,仍得用普通函数 + new.target 方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











