应统一用 const User = class {...} 或 const User = function() {...} 声明构造器,避免 function User() 与 let/const User 同域混用;优先使用模块或 IIFE 隔离作用域,并通过语义化命名(如 UserModel、AdminUser)降低冲突风险。

构造函数本身是函数,一旦与同名变量出现在同一作用域,就会因声明提升或赋值覆盖引发遮蔽(shadowing)或意外覆盖——比如 let User 和 function User() 同时存在时,后者可能被前者静默屏蔽,或在严格模式下直接报错。关键不是“避开名字”,而是**控制声明方式和作用域边界**。
用 class 语法替代 function 声明
ES6 的 class 是语法糖,但它的声明行为更安全:
-
class User不会被变量提升,也不会被同名let User覆盖;相反,同一块级作用域中let User和class User会直接报SyntaxError: Identifier 'User' has already been declared - 即使写成表达式形式:
const User = class { ... },它就完全是一个值,和变量命名规则一致,不会和函数声明机制冲突
避免在同一作用域混用函数声明与 let/const 变量
这是最常见出问题的场景。例如:
function User() {} // 函数声明,会被提升
let User = 'admin'; // ✅ 合法(var 允许,但 let 不允许)→ 实际会报错
上面代码在现代 JS 中会立即抛出 SyntaxError。正确做法是:
立即学习“Java免费学习笔记(深入)”;
- 统一用
const User = function() {...}或const User = class {...},让构造器成为赋值结果,而非声明主体 - 如果必须用
function User(),就不要在同一作用域再出现let User、const User或var User(var虽不报错,但会覆盖函数,极危险)
利用模块或 IIFE 隔离顶层作用域
全局污染是遮蔽的温床。把构造函数封装起来,天然规避冲突:
- ES 模块默认严格作用域:
export class User {...}不会泄漏到全局,其他模块通过import显式使用 - 旧环境可用 IIFE:
(function() { function User() {} window.MyAppUser = User; })();,既保护内部名,又可控暴露 - 不推荐直接挂到
window.User,除非明确设计为全局工具类
命名加前缀或语义化区分
当项目需共存多个相似构造器时,靠命名降低混淆概率:
- 按用途区分:
UserModel(数据层)、UserView(UI 层)、UserAPI(网络层) - 按角色区分:
AdminUser、GuestUser、MockUser - 避免无意义缩写:
U、Usr容易和其他人撞名,也难搜索


















