【问题标题】:Scope of global variables in a Javascript classJavascript 类中全局变量的范围
【发布时间】:2013-01-24 15:45:16
【问题描述】:

我有一个自定义的 Javascript 对象,如下所示:

var CustomClass = function(settings) {

this.var_1 = false;
this.var_2 = null;
this.var_3 = 0;

}

CustomClass.prototype.method_1 = function(){

  var reader = new FileReader();
reader.onload = (function(cropWidget) {
      this.var_1 = true; 
    });
}

CustomClass.prototype.method_2 = function(){

console.log(this.var_1); // logs 'false' onto the console  
if(this.var_1)
 { // proceed further and do something
 }
}

CustomObject 被实例化:

$(document).ready(function{;  
  var customObj = new CustomClass({/*json values*/});
});

然后,另一个 DOM 事件将调用 method_1,例如:

$('#element1').click(function(){
   customObj.method_1(); // this is where var_1 is being set to true
});

问题发生了,当 method_2() 被另一个元素在 DOM 中调用时,像这样:

$('#element2').click(function(){
  customObj.method_2();
});

检查 var_1 的值,正如您所记得的那样,它在 customObj 调用 method_1 时已设置为 true

this.var_1 是假的,而不是应有的真。这是否意味着 var_1 的范围仅针对 method_1() 的范围设置为 true 并且仍然保留它的旧值? IMO Javascript 是通过引用传递的,因此变量值应该在其原始位置设置为 true。

有人可以解释我哪里出错了,以及如何设置 var_1 的值,以便它在 method_2 中也保留它的新值吗?

【问题讨论】:

  • 每次点击#element,都会生成一个 CustomClass 对象。我的猜测是你在一个新对象上调用method_2,而不是同一个对象。
  • “另一个 DOM 事件” - 其他处理程序是否也创建了一个新实例?
  • 向我们展示您实际调用customObj.method_2()的代码
  • 这些点击处理程序是否被绑定内部 相同 $(document).ready处理程序?
  • @ParijatKalia:那么它应该可以工作,因为它对我有用:jsfiddle.net/bre7t

标签: javascript jquery pass-by-reference pass-by-value


【解决方案1】:

问题是您将 var_1 设置为 true 的范围不是您想要的:

CustomClass.prototype.method_1 = function(){

  var reader = new FileReader();
  reader.onload = function(cropWidget) {
    this.var_1 = true;
  };
}

您在回调中将var_ 设置为true,而回调中this 的值method_1 中的相同。

你可以使用self = this 来解决这个问题:

CustomClass.prototype.method_1 = function(){
  // "this" here refers to the CustomClass instance,
  // so let's store it in "self" so we can use it in the callback
  var self = this; 

  var reader = new FileReader();

  reader.onload = function(cropWidget) {
    // "this" here will not be the CustomClass instance, 
    // so we refer to the "self" variable from above.
    self.var_1 = true;
  };
}

这应该可以解决您的问题,尽管仍然存在潜在的时间问题:如果在FileReader 触发其onload 事件之前调用method_2,则var_1 将不会设置为true

【讨论】:

    【解决方案2】:

    this.var_1 是假的,而不是应有的真。

    这很可能是因为您没有引用同一个对象。您的事件处理程序function(){ var customObj = new CustomClass(…); } 创建一个实例并将其分配给一个局部变量。一旦函数运行,它将被垃圾收集。

    IMO javascript 是通过引用传递的,因此变量值应该在其原始位置设置为 true。

    不,javascript 始终是按值传递的。然而,当您传递对象时,您实际上传递的是引用该对象的值,因此会有很多变量引用同一个“共享”对象。

    【讨论】:

    • 我做了一些修改,请重新阅读我的问题以进行修改,
    • 请在您的代码中显示函数的实际嵌套(按照@Rocket 的要求),这会产生巨大的差异。
    猜你喜欢
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2012-01-19
    • 2015-09-30
    • 1970-01-01
    • 2012-07-17
    • 2018-09-02
    • 2012-11-05
    相关资源
    最近更新 更多