【问题标题】:Funny scope issue in Javascript with global variables带有全局变量的 Javascript 中的有趣范围问题
【发布时间】:2016-08-13 05:27:35
【问题描述】:

我有一个包含许多模块的大型 JS 应用程序,最终将与 browersify. 捆绑在一起但由于我不想让我的整个团队在每次更改角色时都安装 Node.js 并重新构建,所以我想要模块在开发时全局注册。我一直在为这样的模块使用标准注册:

// if browserify
if (typeof module === "object" && module.exports) {
    module.exports = myModule;
} else { window.myModule = myModule; }

这就是它变得时髦的地方:当在主 app.js 文件中需要依赖项时,我这样做:

if (typeof module === "object" && module.exports) {
    var myModule = require("./js/myModule");
} // otherwise it's assumed to be globe, which console.log(window) confirms
console.log(myModule);

这个控制台日志以未定义的形式返回,所以我需要一个 else 行,上面写着: } 别的 { myModule = 窗口.myModule; }

这里有一个更简单的jsFiddle 作为概念证明:

if (false) {
    var test = "Hello World";
} else {
  window.test = "Hello Globe";
}

document.getElementById("console").innerHTML = test;

test 在这种情况下未定义。

令我困惑的是,从未运行的if 语句的内容似乎仍然将test 注册为局部变量。是这样吗?还是我只是不明白全局变量是如何工作的?我认为任何注册到window 的东西都可以用它自己的名字来调用,就像我们不必每次都写window.jQuery 一样。

【问题讨论】:

  • 您是否尝试将变量分配给节点中的窗口对象?因为node中没有window对象。
  • var 定义的变量是文件中节点中的全局变量。但是这个范围问题在最新的 Node.js 中得到了解决。 Node 引入 let test = 'Hello';然后测试将无法在 if 之外访问。
  • "从不运行的语句似乎仍然将 test 注册为局部变量" - 确实如此,这就是声明的工作方式。
  • 我想我明白了。这些变量仅在非节点环境中全局分配给窗口。我很惊讶他们在那个(开发)环境中没有全球可用。我按照 Mike Bostock 如何注册 d3: if (typeof define === "function" && define.amd) this.d3 = d3, define(d3);否则 if (typeof module === "object" && module.exports) module.exports = d3;否则 this.d3 = d3;

标签: javascript node.js scope global-variables


【解决方案1】:

Javascript 提升 var 声明,并且由于您在 if 语句中声明这不是新范围,因此基本上是这样的:

if (false) {
    var test = "Hello World";
} else {
  window.test = "Hello Globe";
}

这个也是一样的:

var test;
if (false) {
  test = "Hello World";
} else {
  window.test = "Hello Globe";
}

这就是为什么在作用域的开头声明变量是一种好习惯,请查看以下示例:

var test = "Hello World From outside";
function(){
  console.log(test);
  if (false) {
    var test = "Hello World From inside"
  }
}

这个例子将输出:"undefined" var 测试被提升到作用域的顶部,在这种情况下,函数的顶部覆盖了外部变量声明,尽管我们永远不会进入if

【讨论】:

  • “拥有这个是一样的”部分不太正确。应该是var test; if(false) { test = "Hello World" } 变量声明被提升,而不是赋值。
  • 啊!谷歌搜索“提升”解释了它——我以为我知道我的 JS。谢谢!
猜你喜欢
  • 2012-07-17
  • 2014-09-17
  • 2020-02-29
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多