提升局部变量掩盖全局变量?

Posted

技术标签:

【中文标题】提升局部变量掩盖全局变量?【英文标题】:Hoisted local variable masking global variable? 【发布时间】:2014-11-15 04:17:18 【问题描述】:

node 中遇到了奇怪的行为。我有一个emscripten 编译程序,我想将它用作库。 emscripten 使用变量Module 来控制运行时行为,并生成类似于下面./lib/g.js 的代码。在浏览器中,Module 正确地从index.js 中定义的全局别名到./lib/g.js 中的本地var。但是,在node 中,情况似乎并非如此。构造:var Module = Module || ; 清除了我的全局 Module

index.js:

global.Module =  name: 'Module' ;
var g = require ( './lib/g.js' );

./lib/g.js:

console.log ( 'Module: ', Module );

var Module = Module || ;

node index.js 的输出:

模块:未定义

我假设在g.js 中,Module 仅在本地范围内被提升和取消引用,屏蔽了全局版本(在 global.Module 中)。任何人都可以提出解决方法吗?

可以通过编辑emscripten 生成的代码以使用var Module = global.Module || 来解决此问题。虽然这是一种可能的解决方法,但我宁愿不编辑emscripten 生成的代码。

【问题讨论】:

如果在更高的范围内定义了Module,那么var Module = Module || 只会在这个范围内为其创建一个别名。访问 Module 上的属性可以很好地访问更高范围变量的属性。 @jfriend00:这是预期的行为,但在给出的示例中并没有这样工作。在浏览器中可以正常工作,但在 node 中不能正常工作。没有找到涵盖此案例的 node 的变量范围规则。 看起来 emscripten 确实希望其输出脚本在全局范围内运行,而不是在模块范围内。如果您不想编辑代码,可以尝试全局评估。 在我看来,emscripten 正在使用的全局 Module 与节点使用的全局 Module 之间存在冲突。也许他们都试图定义/使用相同的,或者一个正在重新定义和覆盖另一个。 【参考方案1】:

你可以看看使用rewire

var rewire = require("rewire");
var g = rewire("./lib/g");
g.__set__("Module", name: "Module");

【讨论】:

【参考方案2】:

任何人都可以提出解决方法吗?

只需删除 var 关键字即可。

【讨论】:

为清楚起见编辑了问题。我要避免的是编辑emscripten 生成的代码。更改生成的代码并不总是一个好主意。将直接询问emscripten 社区。​​span>

以上是关于提升局部变量掩盖全局变量?的主要内容,如果未能解决你的问题,请参考以下文章

一言难尽的js变量提升面试题

全局变量局部变量闭包详解

作用域与变量提升

JavaScript作用域:全局作用域局部作用域块级作用域作用域链变量提升

函数声明的提升和变量声明提升

js作用域链以及全局变量和局部变量