【问题标题】:In what scope are module variables stored in node.js?node.js 中存储的模块变量在什么范围内?
【发布时间】:2020-02-10 22:00:22
【问题描述】:

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

var abc = '123';

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

如果我执行这个:

abc = '123';

然后我可以在global.abc 中找到它,但这不是我想要的。

【问题讨论】:

    标签: node.js


    【解决方案1】:

    与浏览器不同,默认情况下变量被分配给全局空间(即窗口),在 Node 中变量的范围是模块(文件)除非你明确将它们分配给 module.exports .

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

    (function (exports, require, module, __filename, __dirname) {
         // your code is here
    });
    

    【讨论】:

    • Node v12.16.1 第一个参数是一个空对象。如果您尝试 console.log 参数变量,您将在数组的第一个位置看到 {}。
    • @YoavKeren 这种变化有什么好处?
    【解决方案2】:

    所有其他答案都是 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'
    

    【讨论】:

    • +1,因为我在开始学习 Node.js 或 JavaScript 时完全是通过 Google 发现的。
    • 这是对 Node.js 中变量作用域的出色描述
    • 很好的答案!使用 var 以外的声明性关键字,如 constletfunction 时怎么样?
    • 有代表模块作用域的对象吗?我想通过包含其名称的变量来访问模块范围变量,可以吗?
    • @CleivsonArruda 好吧,没有办法直接访问模块范围。以下是相应的规范:tc39.github.io/ecma262/#sec-lexical-environments
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      相当老的问题,如果有人对这个问题的 ECMA 规范感到好奇,这里是 link

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 2019-09-10
        • 2022-01-17
        相关资源
        最近更新 更多