JavaScript中检测函数是否被直接调用的核心思路是:通过new.target判断(推荐,ES6+)或检查this指向;new.target在普通调用时为undefined,而this在严格模式下为undefined、非严格模式下不指向实例,可据此抛错或修正。

在 JavaScript 中,检测构造函数是否被直接调用(即未使用 new)的核心思路是:区分 this 的指向或利用语言内置的元属性。直接调用时,this 不会指向新实例;而 new 调用时,this 是新创建的对象,且 new.target 有值。
用 new.target 判断(推荐,ES6+)
new.target 是最简洁、最可靠的方式。它在 new 调用时指向当前函数,在普通调用时为 undefined。
- 如果
new.target === undefined,说明是直接调用,可抛错或自动修正 - 该方式不依赖
this,避免了严格/非严格模式差异和全局污染风险
示例:
function Person(name) {if (!new.target) {
throw new Error('Person 必须用 new 调用');
}
this.name = name;
}
Person('Alice'); // 报错
new Person('Alice'); // 正常
检查 this 是否为实例(兼容 ES5)
利用 this instanceof constructor 判断:普通调用时,this 不是该构造函数的实例(非严格模式下可能是全局对象,严格模式下是 undefined)。
立即学习“Java免费学习笔记(深入)”;
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
- 适用于需支持老环境的项目
- 注意:若构造函数返回对象,
this instanceof仍成立,但实际行为已由返回值决定
示例:
function User(name) {if (!(this instanceof User)) {
throw new Error('请使用 new User()');
}
this.name = name;
}
严格模式 + this 类型判断(防御性更强)
在严格模式下,普通调用时 this 是 undefined,可直接做类型判断,避免误判全局对象。
- 加
'use strict';后,this === undefined就能明确标识非new调用 - 比
instanceof更轻量,且不受原型篡改影响
示例:
'use strict';function Task(desc) {
if (this === undefined) {
throw new Error('Task 必须通过 new 调用');
}
this.desc = desc;
}
结合原型链验证(防伪造)
仅靠 this instanceof 可能被绕过(比如手动设置 this.__proto__ = Constructor.prototype)。更严谨的做法是检查 this 的直接原型是否等于构造函数的 prototype。
- 使用
Object.getPrototypeOf(this) === Constructor.prototype - 适合对安全性要求高的工具类或框架内部逻辑
注意:需确保构造函数的 prototype 未被重写或冻结。

















