严格模式不拦截未授权实例化,仅使非new调用因this为undefined而立即报错;真正拦截需在构造函数内手动校验this instanceof或参数,或改用class+TypeScript实现编译期和运行时双重约束。

严格模式本身不提供“拦截未授权实例化”的能力,它也不会阻止 new 调用。所谓“拦截”,实际是指防止**非 new 调用**(如 Person())导致的意外行为,或在构造函数内部主动拒绝不符合条件的实例化请求。真正的拦截需靠手动检查与设计约束,而非依赖严格模式自动生效。
严格模式的真实作用:让错误调用立刻暴露
启用 "use strict" 后,若有人忘记写 new 直接调用构造函数(例如 Person()),this 不会隐式绑定到全局对象,而是保持为 undefined。此时若构造函数内访问 this.xxx,会立即抛出 TypeError: Cannot set property 'xxx' of undefined。这比静默污染全局更安全,但属于“报错”而非“拦截”——它不阻止调用发生,只让错误无法被忽略。
主动拦截:在构造函数内做实例合法性校验
要真正控制谁可以创建实例、何时可以创建,必须在函数体开头插入显式判断逻辑:
-
检查调用方式是否合法:用
!(this instanceof Person)判断是否被new调用,不满足则抛错或返回缓存实例(适用于单例场景) -
校验参数或上下文:比如要求传入 token、特定环境标识,或检查
document是否存在(浏览器专属类) -
结合静态标记限制重复创建:如设置
Person._instantiated = true,首次后直接返回已有实例或抛错
更可靠的替代方案:用 class + TypeScript 强制约束
ES6 的 class 构造器天然禁止非 new 调用:Person() 会直接报 TypeError: Class constructor Person cannot be invoked without 'new',无需手写检查。配合 TypeScript,还能在编译期拦截非法调用(如类型不匹配、缺少必传参数)。这对团队协作和长期维护更有效,也避免运行时才发现问题。
立即学习“Java免费学习笔记(深入)”;
注意 Proxy 不能用于拦截 new 操作
Proxy 只能拦截已存在对象上的操作(如 get、set),无法拦截 new Person() 这一创建过程本身。你无法用 Proxy “包装构造函数”来阻止实例化——new 是语言级操作,不在 Proxy 的 trap 覆盖范围内。想控制构造行为,只能从函数内部逻辑或类型系统入手。


















