Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从实例化对象到外部作用域的变量引用如何在NodeJS中工作_Javascript_Node.js_Scope_Closures - Fatal编程技术网

Javascript 从实例化对象到外部作用域的变量引用如何在NodeJS中工作

Javascript 从实例化对象到外部作用域的变量引用如何在NodeJS中工作,javascript,node.js,scope,closures,Javascript,Node.js,Scope,Closures,对于范围如何被内部对象看到/与之相关,我有点困惑。我理解作用域定义了变量的封闭/查看方式,上下文指的是创建并绑定到一个对象,内部对象和函数可以访问全局对象;然而,我不明白作用域如何(或是否)与对象相关 如何在引擎盖下进行范围界定 通过(a)将包含外部变量的绑定到对象或(b)将该变量添加到全局对象,是否是访问对象中外部变量的唯一方法?或者,对象是否使用javascript作用域引用外部作用域 我正在尝试设置一个NodeJS web服务器,并希望定义一个本地变量,该变量可以被条目(索引)文件中构造的

对于范围如何被内部对象看到/与之相关,我有点困惑。我理解作用域定义了变量的封闭/查看方式,上下文指的是创建并绑定到一个对象,内部对象和函数可以访问全局对象;然而,我不明白作用域如何(或是否)与对象相关

  • 如何在引擎盖下进行范围界定
  • 通过(a)将包含外部变量的<代码>绑定到对象或(b)将该变量添加到全局对象,是否是访问对象中外部变量的唯一方法?或者,对象是否使用javascript作用域引用外部作用域
  • 我正在尝试设置一个NodeJS web服务器,并希望定义一个本地变量,该变量可以被条目(索引)文件中构造的所有其他内部对象访问。我试着用
    var x=10来实现这一点;然而,当我试图从稍后在代码中实例化的对象访问变量时,无法访问该变量。我使用
    new
    操作符实例化了一个对象,然后调用了该对象中的一个方法,该方法将
    x
    记录到控制台,但我得到了一个“x未定义”错误。在chrome中调试时,我在任何地方都找不到定义的
    x
    。我看到了全局上下文,它似乎只是全局对象,我看到了局部上下文,它似乎是实例化的对象,但我没有看到对实例化对象的上下文的引用。我可以把变量放在全局对象上,然后它就可以被引用,但我不想养成把所有东西都放在全局对象上的坏习惯

    顶层(名为startup.js的文件,使用
    节点startup.js
    调用):

    控制器文件:

    class Controller {
      constructor()
    
      createEntry(entry, callback) {
         console.log(x);
         return callback(entry);
      }
    }
    
    module.exports = Controller;
    
  • 我希望能够在公认的良好实践模式中从内部范围引用
    x
    。如果在比实例化对象中的方法更高级的上下文中使用变量是不可能的,那么如果您能建议一种替代方法(最好不要附加到全局对象),我将非常感激。 谢谢你的时间和帮助,请让我知道,如果和如何我可以改善后
    示例中的
    x
    只能由
    startup.js
    中的代码访问。其他任何地方都无法访问它。它不是一个全局的(我想你已经知道了),它是
    startup.js
    模块中的一个全局模块

    要使
    控制器
    的代码可以访问它,通常要做的事情是将它作为参数传递给
    控制器

    var controller = new Controller(props, x);
    // ------------------------------------^
    
    它不会传递变量,但会传递该行代码执行时变量的当前值

    如果要传递
    Controller
    某些即使更改也会看到
    x
    当前值的对象,则应将
    x
    作为属性放入对象中,并将对象引用传递给
    Controller

    var stuff = {x: 10};
    // ...
    var controller = new Controller(props, stuff);
    
    Controller
    会记住对象引用,然后在该对象上查找
    x

    class Controller {
      constructor(props, stuff) {
          this.stuff = stuff; // <====
      }
    
      createEntry(entry, callback) {
         console.log(stuff.x);
         // ---------^^^^^^
         return callback(entry);
      }
    }
    
    module.exports = Controller;
    
    …并让
    controller.js
    和其他需要它加载模块的内容:

    var stuff = require("./stuff");
    // ...
    class Controller {
      constructor(props) {
      }
    
      createEntry(entry, callback) {
         console.log(stuff.x);
         // ---------^^^^^^
         return callback(entry);
      }
    }
    
    我认为以上回答了问题2和问题3,但是:

    一,。如何在引擎盖下进行范围界定

    范围界定是一个词汇(文本)概念,它确定代码可以访问哪些标识符等。作用域的工作方式类似于嵌套框:每个作用域都可以访问其包含作用域中的所有内容。例如:

    var x;
    // Code here has access to `x`
    function outer() {
        var y;
    
        // Code here has access to `x` and `y`
    
        function inner() {
            var z;
    
            // Code here has access to `x`, `y`, and `z`
        }
    
        inner();
    }
    
    outer();
    
    你可能会想:“嘿,等等,但是如果你调用
    outer
    两次呢?然后有两个
    y
    s!”你完全正确,有!还有两个
    内部
    s。每个
    internal
    都可以访问相同的
    x
    ,但每个
    y
    :为调用创建
    internal
    y
    而创建的
    y

    闭包就是这样工作的。更多:

    • (在我贫血的小博客上,这是一篇使用了一些过时术语的老文章,但概念保持不变)
    • (此处仅此而已)

    Re
    this.x
    :您提到使用
    this
    访问
    x
    (例如,
    this.x
    )。该机制(
    this.x
    )查找对象的属性。相反,您的
    x
    变量不是属性,而是变量。JavaScript对象和作用域之间没有太多关系。尽管我们经常将作用域概念化为在幕后使用隐藏对象(规范当然是这样),但这些对象纯粹是概念性的,在代码中不可访问(只有一个例外:全局对象,它既是真实对象,又是用
    var
    和全局声明函数声明的全局变量的容器)[但不适用于使用
    let
    const
    声明的变量,或使用
    class
    ]定义的类]

    如何在引擎盖下进行范围界定

    范围由函数(
    var
    )或块(
    let
    )分隔

    如果
    var
    在同一个函数中,或者
    let
    在同一个块中,您可以访问它

    如果当前范围是在变量可用的范围内定义的,那么您可以访问它,除非它在更窄的范围内被另一个同名变量屏蔽

    通过(a)将包含外部变量的this绑定到对象,或者(b)将该变量添加到全局对象,或者,对象是否使用javascript作用域引用外部作用域,来访问对象中的外部变量是唯一的方法

    您的案例(a)无法访问变量。对象属性不是变量

    您的案例(b)只意味着变量存储在尽可能宽的范围内。最好避免全局变量。保持范围尽可能宽
    var stuff = require("./stuff");
    // ...
    class Controller {
      constructor(props) {
      }
    
      createEntry(entry, callback) {
         console.log(stuff.x);
         // ---------^^^^^^
         return callback(entry);
      }
    }
    
    var x;
    // Code here has access to `x`
    function outer() {
        var y;
    
        // Code here has access to `x` and `y`
    
        function inner() {
            var z;
    
            // Code here has access to `x`, `y`, and `z`
        }
    
        inner();
    }
    
    outer();