模块变量在什么范围内存储在node.js中?

ske*_*rit 34 node.js

当我在node.js模块中执行此操作时:

var abc = '123';
Run Code Online (Sandbox Code Playgroud)

它去哪儿了?我的意思是:在浏览器中它进入window.abc(如果没有在函数或其他方面执行)

如果我执行这个:

abc = '123';
Run Code Online (Sandbox Code Playgroud)

然后我可以找到它global.abc,但那不是我想要的.

Hec*_*rea 64

与浏览器不同,默认情况下,变量被分配给全局空间(即窗口),而节点变量的范围限定为模块(文件),除非您明确地将它们分配给module.exports.

实际上,当您运行node myfile.jsrequire('somefile.js')文件中的代码包装如下:

(function (exports, require, module, __filename, __dirname) {
     // your code is here
});
Run Code Online (Sandbox Code Playgroud)


Toa*_*ish 54

所有其他答案都是100%正确,但我想我会在Node.js应用程序中添加一个扩展/确定的范围列表,以防任何人在开始学习Node.js或JavaScript时遇到这个问题:

全球范围

任何var在任何文件中没有关键字声明的内容都可以在Node服务器的同一实例中运行的任何地方访问:

// foo.js
bar = 'baz';


// qux.js
console.log(bar); // prints 'baz'
Run Code Online (Sandbox Code Playgroud)

请注意,这被广泛认为是一个坏主意,因为它会使您的应用程序强烈"耦合" - 这意味着您必须打开foo.js以找出bar = 'baz'qux.js中的原因

模块范围

var在node.js文件的顶层(不在函数或对象或任何其他块内)使用关键字声明的任何内容都在模块范围内,并且可以从同一文件中的任何位置访问,但在其他任何地方都不会存在:

// foo.js
var bar = 'baz';
console.log(bar); // prints 'baz'


// qux.js
console.log(bar); // prints 'undefined'
Run Code Online (Sandbox Code Playgroud)

功能范围

var在函数中使用关键字声明的任何内容都只能从该函数中访问,而不能从其他任何地方访问:

// foo.js
function myFunction() {
  var bar = 'baz';
  console.log(bar); // prints 'baz'
}

function myOtherFunction() {
  console.log(bar); // prints 'undefined'
}



// qux.js
console.log(bar); // prints 'undefined'
Run Code Online (Sandbox Code Playgroud)

JavaScript是功能范围的.与其他(块范围)语言不同,在函数中的块中声明的变量可以从该父函数中的任何其他位置访问.例如,这意味着如果在循环内部声明一个新变量,它也可以在该循环外部访问,只要您仍在父函数内:

function myFunction() {
  while (thing === true) {
  var bar = 'baz';
  thing = false;
  }
  console.log(bar); // prints 'baz'
}
Run Code Online (Sandbox Code Playgroud)

阴影

如果您'重新声明'现有变量,例如使用var已经使用过的变量名称的关键字,则在新声明的范围内覆盖与该变量名称关联的值:

var bar = 'foo';
console.log(bar) // prints 'foo'

function myFunction() {
  var bar = 'baz';
  console.log(bar);
}
myFunction(); // prints 'baz'
console.log(bar) // prints 'foo'
Run Code Online (Sandbox Code Playgroud)

  • +1,因为我在开始学习Node.js或JavaScript时完全通过Google遇到过这个问题. (6认同)
  • 很棒的答案!当使用`var`以外的声明性关键字时,如`const`,`let`或`function`怎么样? (2认同)
  • 是否有一个对象来表示模块范围?我想通过包含其名称的变量访问模块范围变量,这可能吗? (2认同)

rob*_*lep 5

Node 有一个模块作用域,所以var abc = '123'在一个模块中将创建一个变量,该变量作用域为(因此,只有代码可以访问)该模块。

另见http://nodejs.org/api/globals.html#globals_global


loa*_*age 5

很老的问题,如果有人对这个问题的 ECMA 规范感到好奇,这里是链接

并且无法直接访问模块变量(导入的模块除外):

词法环境和环境记录值纯粹是规范机制,不需要对应于 ECMAScript 实现的任何特定制品。ECMAScript 程序不可能直接访问或操作这些值。