Node.js中vm.runInThisContext变量作用域差异的技术问询
为什么
vm.runInThisContext的B场景下a不会添加到全局对象? 要搞懂这个问题,得结合两个核心点:vm.runInThisContext的作用域规则和JavaScript变量声明的作用域特性。
先明确vm.runInThisContext的基础行为
这个方法运行代码时,不会引入当前模块的本地作用域,但会直接绑定全局对象作为代码运行的顶层作用域。也就是说,代码里的顶层作用域操作会直接作用于全局对象,但函数内部的作用域依然遵循JS本身的规则。
拆解第一个例子的共性
不管是A还是B:
A) vm.runInThisContext("a=5;") B) vm.runInThisContext("var a=5;")
- 代码都是在顶层作用域执行:
- A里的
a=5没有声明,属于隐式赋值,JS会自动在顶层作用域(也就是全局对象)创建这个变量。 - B里的
var a=5是顶层声明,在JS中,顶层作用域的var声明会直接成为全局对象的属性。
所以两种情况都会把a挂到全局。
- A里的
拆解第二个例子的差异
场景A:
vm.runInThisContext('function test(){ a = 5;} test()')
函数test内部的a=5没有用var/let/const声明,属于隐式全局变量。当函数执行时,JS会先在当前函数作用域找a,找不到就沿着作用域链往上找,最终找到全局对象,然后把a挂载到全局上。
场景B:
vm.runInThisContext('function test(){ var a = 5;} test()')
函数test内部的var a=5是函数作用域的声明:
var的作用域是当前函数,所以这个a只存在于test函数的内部作用域中,是局部变量。- 函数执行时,JS不会往全局作用域找这个变量,自然也就不会把它添加到全局对象里。
简单说,就是var把a的作用域锁死在了函数内部,和全局对象没有关系。
内容的提问来源于stack exchange,提问作者Giorgi Lagidze
相关产品推荐
相关产品推荐

