构造函数漏写new会导致this指向错误,防范方式包括:①构造函数内用instanceof检查并抛错;②改用class语法(天然禁止无new调用);③使用new.target判断;④配合typescript或eslint提前拦截。

漏写 new 是构造函数最常见也最危险的误用——它不会语法报错,但会导致 this 指向错误,轻则属性挂到全局,重则逻辑崩溃。防范的核心不是靠“运气”或“约定”,而是主动拦截和明确约束。
在构造函数开头做 instanceof 检查
这是最直接、兼容性最好、无需额外工具的方式。只要 this 不是当前构造函数的实例,就立刻抛错:
- 写法示例:
if (!(this instanceof Person)) throw new Error('Person 必须用 new 调用') - 它在非严格/严格模式下都有效,且不依赖环境(浏览器、Node、打包后)
- 即使被压缩混淆,逻辑依然生效;比注释或命名约定更可靠
改用 class 语法替代 function 构造函数
class 是 ES6 提供的语法糖,底层仍是原型机制,但它天然禁止无 new 调用:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 写
const p = Person()会直接报TypeError: Class constructor Person cannot be invoked without 'new' - 不需要手动写
instanceof检查,错误发生在调用时而非运行中 - 配合字段声明(如
name = '')和私有字段(#id),初始化更清晰
用 new.target 做运行时判断(现代环境推荐)
new.target 是专为识别 new 调用设计的元属性,语义最准确:
- 在构造函数内:
if (!new.target) throw new Error('请使用 new 调用') - 它比
instanceof更底层——不依赖原型链是否被修改,也不受继承干扰 - 支持子类继承(
super()中也能访问),适合复杂继承结构 - 注意:IE 不支持,若需兼容旧环境,应回退到
instanceof方案
配合 TypeScript 或静态检查提前拦截
真正防患于未然,是在代码写完、运行之前就发现问题:
- TypeScript 中定义
declare class Person后,Person()会被类型系统标红,提示“Cannot use 'Person' as a function” - ESLint 插件如
no-new-func或自定义规则可检测未加new的大驼峰函数调用 - CI 流程中加入类型检查和 lint,让错误止步于提交前










