Javascript中带有全局变量的有趣范围问题

Javascript中带有全局变量的有趣范围问题,javascript,node.js,scope,global-variables,Javascript,Node.js,Scope,Global Variables,我有一个包含许多模块的大型JS应用程序,最终将与browersify捆绑。但由于我不想让我的整个团队在每次更改角色时都安装Node.JS并重建,我希望模块在开发过程中进行全局注册。我一直在使用标准注册模块,例如: // if browserify if (typeof module === "object" && module.exports) { module.exports = myModule; } else { window.myModule = myModule

我有一个包含许多模块的大型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=window.myModule; }

以下是一个更简单的概念证明:

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

document.getElementById("console").innerHTML = test;
test
在此场景中未定义


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

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";
}
这和拥有这个是一样的:

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"
  }
}

此示例将输出:“未定义”var测试被提升到范围的顶部,在这种情况下,函数顶部覆盖外部变量声明,尽管我们永远不会进入
if

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";
}
这和拥有这个是一样的:

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测试被提升到作用域的顶部,在这种情况下,覆盖外部变量声明的函数顶部,尽管如果您试图将变量分配给节点中的窗口对象,我们将永远不会进入该
?因为节点中没有窗口对象。使用var定义的变量是文件中节点中的全局变量。但这个范围问题在最新节点中得到了解决。节点引入let test='Hello';那个么,测试将无法从if外部访问。“从未运行的语句似乎仍然将测试注册为局部变量”-当然,声明就是这样工作的。我想我理解。变量仅全局分配给非节点环境中的窗口。我只是感到惊讶的是,在那个(开发)环境中,它们并没有在全球范围内可用。我在看Mike Bostock如何注册d3:if(typeof define==“function”&&define.amd)this.d3=d3,define(d3);如果(模块类型==“对象”&&module.exports)module.exports=d3;否则,该值为0.d3=d3;是否尝试将变量分配给节点中的窗口对象?因为节点中没有窗口对象。使用var定义的变量是文件中节点中的全局变量。但这个范围问题在最新节点中得到了解决。节点引入let test='Hello';那个么,测试将无法从if外部访问。“从未运行的语句似乎仍然将测试注册为局部变量”-当然,声明就是这样工作的。我想我理解。变量仅全局分配给非节点环境中的窗口。我只是感到惊讶的是,在那个(开发)环境中,它们并没有在全球范围内可用。我在看Mike Bostock如何注册d3:if(typeof define==“function”&&define.amd)this.d3=d3,define(d3);如果(模块类型==“对象”&&module.exports)module.exports=d3;否则,该值为0.d3=d3;“这和拥有这个一样”的部分不太正确。它应该是
var测试;如果(false){test=“Hello World”}
变量声明被挂起,而不是赋值。啊!谷歌搜索“吊装”解释了这一点——我想我知道我的JS。谢谢“这和拥有这个一样”的部分不太正确。它应该是
var测试;如果(false){test=“Hello World”}
变量声明被挂起,而不是赋值。啊!谷歌搜索“吊装”解释了这一点——我想我知道我的JS。谢谢