Javascript类中全局变量的范围

时间:2013-02-08 19:30:57

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

我有一个自定义的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
});

问题发生了,当DOM中的method_2()被另一个元素调用时,如下所示:

$('#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中保留它的新值?

2 个答案:

答案 0 :(得分:2)

  

this.var_1是假的,不应该是真的。

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

  

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

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

答案 1 :(得分:2)

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

CustomClass.prototype.method_1 = function(){

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

您在回调中将var_设置为true,并且回调中this的值 与{中}相同{1}}。

您可以使用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; }; } 触发其method_2事件之前调用FileReader,则onload赢了&#39 ; t尚未设置为var_1