知识卡片
隐式全局难调试
内容
旧式非严格脚本中,给未加 var 声明的变量赋值(foo = value)会创建隐式全局变量,本意方便初学者省略声明,实际后果是拼写错误被当合法赋值放行,导致 bug 极难定位。此行为仅限旧式非严格脚本:严格模式和 ES 模块会直接抛 ReferenceError,见 [[严格模式阻止隐式全局]]。发散:严格声明、静态检查和模块作用域的价值,首先是把这种低级错误尽早暴露。
参考来源
- 位置:《JavaScript语言精粹(修订版)》附录A《毒瘤 Awful Parts》"全局变量"一节
- 结论依据:原文说明定义全局变量的第三种方式是"直接使用未经声明的变量,这被称为隐式的全局变量",其设计初衷是方便初学者省略声明,但"忘记声明变量成了一个非常普遍的错误……这导致查找bug非常困难";据此保留原书对旧式行为的判断,但按 MDN 严格模式文档补上现代限定:该行为仅存在于非严格脚本,严格模式/模块会抛错。
- 原始内容:第3种是直接使用未经声明的变量,这被称为隐式的全局变量……这种方式本来是为方便初学者,有意让变量在使用前无须声明。遗憾的是,忘记声明变量成了一个非常普遍的错误。JavaScript的策略是让那些忘记预先声明的变量成为全局变量,这导致查找bug非常困难。