【问题标题】:Scope of variables in JSJS中变量的作用域
【发布时间】:2015-03-17 14:17:01
【问题描述】:

请看下面的JS sn-p:

var MyClass = function() {
    var logging = true;

    this.myFunction = function(logging) {

    }
}

myObj = new MyClass();
myObj.myFunction(false);

有没有办法访问 myFunction 中的两个 logging 变量?

我能想出的唯一解决方案(this.logging)似乎不起作用: https://jsfiddle.net/x7m3w3gp/

【问题讨论】:

    标签: javascript scope closures


    【解决方案1】:

    myFunction 方法中的代码中,无法从其外部范围访问局部变量,因为参数会隐藏变量。

    使用this.logging 不会访问变量,它会访问同名对象的属性。

    您可以在该范围内放置一个可以访问该变量的函数,用作myFunction 方法的桥梁。

    变量、属性和桥的用法示例:

    var MyClass = function() {
        // local variable
        var logging = true;
        // property
        this.logging = 1;
    
        // bridge local variable
        function getLogging() { return logging; }
    
        this.myFunction = function(logging) {
          console.log(logging); // parameter
          console.log(this.logging); // property
          console.log(getLogging()); // local variable
        }
    }
    
    myObj = new MyClass();
    myObj.myFunction(false);
    

    【讨论】:

    • 谢谢! getter 方法最适合我,因为不应通过例如myObj.logging 访问局部变量 logging
    【解决方案2】:

    在您的代码中,您创建的匿名函数的形式参数与局部变量具有相同的名称(在这两种情况下都是“记录”)。在该匿名函数(最终成为“myFunction”属性的函数)中,符号“logging”将引用该参数。无法访问也称为“日志记录”的局部变量。

    解决这个问题的方法是给参数一个不同的名字。

    请注意,this.logging 将引用名为“logging”的属性,如果有的话。在您发布的代码中,没有任何此类属性。

    【讨论】:

      【解决方案3】:

      尝试将日志记录定义为 MyClass 的属性。这应该有效:

      var MyClass = function() {
          this.logging = true;
      }
      
      
      MyClass.prototype.myFunction = function(logging) {
          /*References the logging-Property of the MyClass-Object:*/
          var log1 = this.logging;
      
           /*References the parameter:*/
          var log2 = logging;
      }
      
      myObj = new MyClass();
      myObj.myFunction(false);
      

      【讨论】:

      • prototype 与此无关。
      • 虽然这样的事情可能会解决 OP 问题,但请注意,将“日志记录”变量作为对象属性公开与在闭包中保留私有变量有很大不同。
      【解决方案4】:

      这应该有效;

      var MyClass = function() {
          this.logging = true;
          var logging = 0;
      
          this.myFunction = function(logging) {
              var console = document.getElementById('console');
              console.innerHTML = 'logging: ' + logging + '<br />';
              console.innerHTML += 'this.logging: ' + this.logging + '<br/>';
              console.innerHTML += 'var loggin:' + logging + ' !!! <br/>--> var logging scope never access';
          }
      }
      
      myObj = new MyClass();
      myObj.myFunction(false);
      

      https://jsfiddle.net/x7m3w3gp/2/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-24
        • 2011-02-17
        • 2014-07-11
        • 2010-12-12
        相关资源
        最近更新 更多