You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中为何仅间接eval内的var声明会挂载到globalThis?

为什么Node.js中只有间接eval内的var会挂载到globalThis?

核心原因在于eval的调用方式(直接/间接)决定了它的执行作用域,再结合Node.js的模块作用域机制,就导致了这种差异:

1. demo1.js的情况:函数/IIFE内的var不会挂全局

Node.js的每个文件都是一个独立的模块作用域,而非全局作用域:

  • 函数baz内的var var4:变量作用域被严格限制在函数内部,和全局对象完全无关。
  • IIFE内的var var5:IIFE的作用域是模块作用域的子作用域,var声明的变量会提升到模块顶层,但模块作用域的变量不会自动挂载到globalThis——Node.js模块的设计初衷就是隔离全局污染,顶层变量仅在模块内部可见。

示例代码运行结果:

// demo1.js
function baz() {
  var var4 = 'baz';
}
(function() {
  var var5 = 'iife';
})();

console.log(globalThis.var4); // undefined
console.log(globalThis.var5); // undefined
console.log(var5); // ReferenceError: var5 is not defined

2. demo2.js的情况:间接eval的var会挂全局

根据ECMAScript规范,间接调用eval时,代码会在全局执行上下文中求值,而非当前的函数/模块作用域:

  • 间接调用的常见形式:把eval赋值给变量后调用(var e = eval; e(...))、用call/apply调用、或者在非直接引用eval标识符的场景下调用。
  • 在Node.js中,全局执行上下文的变量对象就是globalThis,所以间接eval里用var声明的变量,会直接成为globalThis的属性。

示例代码运行结果:

// demo2.js
(function() {
  // 间接调用eval
  const evalFn = eval;
  evalFn('var foo = 123');
})();

console.log(globalThis.foo); // 123

补充:直接eval vs 间接eval的关键区别

  • 直接eval:直接写eval(...),代码在当前作用域执行。比如在模块的IIFE里直接调用eval('var bar = 456'),bar会成为模块作用域的变量,不会挂载到globalThis。
  • 间接eval:任何不直接引用eval标识符的调用,都会触发全局作用域执行,此时var声明的变量会绑定到全局对象。

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 21:56:06