【发布时间】:2020-02-10 22:00:22
【问题描述】:
当我在我的 node.js 模块中执行此操作时:
var abc = '123';
它去哪儿了?我的意思是:在浏览器中它进入window.abc(如果没有在函数中执行或以其他方式执行)
如果我执行这个:
abc = '123';
然后我可以在global.abc 中找到它,但这不是我想要的。
【问题讨论】:
标签: node.js
当我在我的 node.js 模块中执行此操作时:
var abc = '123';
它去哪儿了?我的意思是:在浏览器中它进入window.abc(如果没有在函数中执行或以其他方式执行)
如果我执行这个:
abc = '123';
然后我可以在global.abc 中找到它,但这不是我想要的。
【问题讨论】:
标签: node.js
与浏览器不同,默认情况下变量被分配给全局空间(即窗口),在 Node 中变量的范围是模块(文件)除非你明确将它们分配给 module.exports .
实际上,当您运行node myfile.js 或require('somefile.js') 时,文件中的代码如下包装:
(function (exports, require, module, __filename, __dirname) {
// your code is here
});
【讨论】:
所有其他答案都是 100% 正确的,但我想我会在 Node.js 应用程序中添加一个扩展/明确的范围列表,以防有人在开始学习 Node.js 或 JavaScript 时通过 Google 遇到这个问题:
任何文件中没有var 关键字声明的任何内容都可以从运行在同一节点服务器实例中的任何位置访问:
// foo.js
bar = 'baz';
// qux.js
console.log(bar); // prints 'baz'
请注意,这被广泛认为是一个坏主意,因为它使您的应用程序强“耦合”——这意味着您必须打开 foo.js 才能找出 qux.js 中 bar = 'baz' 的原因
在 node.js 文件的顶层(不在函数或对象或任何其他块内)使用 var 关键字声明的任何内容都在 模块范围 中,并且可以访问来自同一文件中的任何位置,但不会存在于其他任何位置:
// foo.js
var bar = 'baz';
console.log(bar); // prints 'baz'
// qux.js
console.log(bar); // prints 'undefined'
在函数中使用 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'
JavaScript is function scoped。与其他(块范围)语言不同,在函数内的块中声明的变量可以从该父函数中的其他任何地方访问。例如,这意味着如果您在循环内声明一个新变量,那么只要您仍在父函数内,它也可以在该循环外访问:
function myFunction() {
while (thing === true) {
var bar = 'baz';
thing = false;
}
console.log(bar); // prints 'baz'
}
如果您“重新声明”现有变量,例如将 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'
【讨论】:
var 以外的声明性关键字,如 const、let 或 function 时怎么样?
Node 有一个模块作用域,因此模块中的var abc = '123' 将创建一个作用域为该模块的变量(因此,仅对其中的代码可访问)。
【讨论】:
相当老的问题,如果有人对这个问题的 ECMA 规范感到好奇,这里是 link
并且没有办法直接访问模块变量(导入的模块除外):
词法环境和环境记录值纯粹是规范机制,不需要对应于 ECMAScript 实现的任何特定工件。 ECMAScript 程序不可能直接访问或操作这些值。
【讨论】: