为什么在没有`var`的情况下访问变量而不必在其他文件中使用`require`?

时间:2013-07-30 15:51:07

标签: node.js

这是一个例子

$ cat main.js
App = {
  version : 1.1
};
require('./mymod.js');

$ cat mymod.js
console.log(App.version);

$ node main.js
1.1

请注意我在没有App的main.js中声明var的方式。这样,我就可以从App访问mymod.js,而无需致电require。如果我使用App声明var,则无效。

我想明白为什么会这样?它是node.js或bug的预期行为吗?这种行为是否与ECMAScript或CommonJS标准一致?

这个技巧提供了一种强大的机制来绕过node.js的require模块系统。在每个文件中定义您的对象并将它们添加到顶级App命名空间。您在其他文件中的代码将自动访问这些对象。我错过了什么吗?

4 个答案:

答案 0 :(得分:8)

如果在不使用var的情况下分配变量,则它自动为全局变量。这就是JavaScript的工作方式。如果您将'use strict';(需要引号)放在js文件的顶部,则会出现错误。

答案 1 :(得分:1)

所有这些都与本地范围和全球范围有关。

你甚至可以这样做(更整洁):

app.js:

exports = {
  version : 1.1
}; 

main.js:

var App = require('./app.js');
console.log(App.version);

答案 2 :(得分:1)

定义一个没有前面的var的变量会将它放入全局命名空间,这对所有JavaScript代码都是可见的。

虽然这似乎是一个有用的功能,但通常认为“污染”全局命名空间是不好的做法,并且当两个非相关文件都依赖或定义变量时,可能导致细微的,难以定位的错误。同名。

答案 3 :(得分:-1)

在nodeJS环境中,有一个全局范围由'global'引用,就像我们在浏览器环境中拥有'window'一样。实际上,每个javascript主机环境总是从创建全局对象开始。

当执行require('main.js')时,会有以下函数针对全局范围'global'创建和执行。

(function(exports,...){
   //content of main.js
   App = {
     version : 1.1
  };
})(module.exports,..);

执行上述函数时,由于App没有var声明,因此在全局对象上创建名为“App”的属性并赋值。此行为符合ECMA规范。

这就是应用程序进入全局范围并可在所有模块中访问的方式。

require已被引入,以标准化可以移植和使用的模块的开发。