最直接可靠的方式是使用 new.target:若通过 new 调用,new.target 指向函数本身;否则为 undefined;推荐 es6+ 使用,配合 instanceof、原型链检查及首字母大写命名约定可增强健壮性。

最直接可靠的方式是使用 new.target,它是 ES6 引入的原生机制,专为检测是否通过 new 调用而设计。
用 new.target 判断(推荐,ES6+)
new.target 在函数内部始终可用:
- 如果函数是通过
new调用的,new.target指向该函数本身(或子类构造器); - 如果是普通调用,
new.target为undefined。
示例:
function User(name) {
if (!new.target) {
throw new Error('User 必须用 new 调用');
}
this.name = name;
}
new User('Alice'); // ✅ 正常
User('Bob'); // ❌ 抛出错误
用 instanceof 检查 this(兼容 ES5)
在函数体内判断 this 是否为当前函数的实例:
- 通过
this instanceof User可大致识别是否为new调用; - 但要注意:若函数被显式绑定(如
call/apply),或在非严格模式下被普通调用,this可能指向全局对象(如window),导致误判; - 建议配合
'use strict'使用,避免this意外指向全局。
示例:
function User(name) {
'use strict';
if (!(this instanceof User)) {
throw new Error('请使用 new 调用 User');
}
this.name = name;
}
检查原型链是否匹配(更严谨的 instanceof 替代)
避免 instanceof 在跨执行上下文(如 iframe)中失效的问题,可改用 Object.getPrototypeOf(this) === User.prototype:
- 确保
this的直接原型就是构造函数的prototype; - 需提前确保
User.prototype未被意外覆盖(例如通过User.prototype = {...}后要手动修复constructor)。
命名约定辅助提醒(非技术拦截)
虽然不能阻止误调,但能显著降低出错概率:
- 构造函数首字母大写(如
User,ApiClient); - 普通函数小驼峰(如
createUser,validateInput); - 团队协作和代码审查时,这种视觉提示非常有效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











