为什么Node环境中var/let声明的全局变量未挂载到globalThis下
差异原因详解
这个现象和Node版本没有直接关联,核心是不同JS运行环境的顶层作用域规则不同:
- 浏览器环境下,脚本的顶层作用域就是全局作用域,用
var在顶层声明的变量会自动成为globalThis的不可配置属性,delete操作无法删除这类属性,所以会返回false,这就是《JavaScript权威指南》中示例对应的场景,也是你在Stack Overflow在线运行环境(默认模拟浏览器脚本执行逻辑)得到符合预期结果的原因。 - Node.js环境默认所有.js文件都是独立的CommonJS模块,文件内的顶层作用域实际是当前模块的私有作用域,你写的
var x = 1只是模块内的局部变量,根本不会挂载到globalThis上,delete globalThis.x本质是删除一个不存在的属性,JS规范中删除对象不存在的属性默认返回true,这就是你得到和书中相反结果的原因。 - 未加声明关键字直接赋值的
x = 1会成为全局属性,是因为JS规范规定未声明直接赋值的变量会被自动注册为globalThis的可配置属性,这个行为在浏览器和Node环境中是统一的。
如果你要在Node环境复现书中的示例结果,可选两种方案:
- 直接在Node交互式REPL终端中执行代码,REPL的顶层作用域就是全局作用域,
var声明的顶层变量会自动挂载到globalThis - 将代码作为顶层输入直接传给Node执行,不需要放在.js文件里,比如执行命令:
echo "var x = 1; console.log(delete globalThis.x)" | node
这时候输出结果就会是false,和书中描述完全一致。
内容的提问来源于stack exchange,提问作者Verner Keel
相关产品推荐
相关产品推荐

