最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Scope of global variables in a Javascript class - Stack Overflow

programmeradmin2浏览0评论

I have a custom Javascript object, that looks like this:

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
 }
}

The CustomObject is instantiated upon:

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

And then, another DOM event will call upon method_1 like:

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

The problem happens, when method_2() is being invoked in the DOM by another element, like this:

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

it checks for the value of var_1 which as you would recall has been set to true when customObj invoked method_1

this.var_1 is false, and not true as it should be. Does this mean the scope of var_1 was set to true only for the scope of the method_1() and still retains it's older value? IMO Javascript is pass by reference, so that variable value should have been set to true in it's original place.

Can someone explain where I am going wrong and how I may go about setting the value of var_1 such that it retains it's new value in method_2 as well ?

I have a custom Javascript object, that looks like this:

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
 }
}

The CustomObject is instantiated upon:

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

And then, another DOM event will call upon method_1 like:

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

The problem happens, when method_2() is being invoked in the DOM by another element, like this:

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

it checks for the value of var_1 which as you would recall has been set to true when customObj invoked method_1

this.var_1 is false, and not true as it should be. Does this mean the scope of var_1 was set to true only for the scope of the method_1() and still retains it's older value? IMO Javascript is pass by reference, so that variable value should have been set to true in it's original place.

Can someone explain where I am going wrong and how I may go about setting the value of var_1 such that it retains it's new value in method_2 as well ?

Share Improve this question edited Feb 8, 2013 at 20:20 Parijat Kalia asked Feb 8, 2013 at 19:30 Parijat KaliaParijat Kalia 5,10512 gold badges54 silver badges78 bronze badges 12
  • 6 Every time you click on #element, it makes a new CustomClass object. My guess is that you are calling method_2 on a new object, instead of the same one. – gen_Eric Commented Feb 8, 2013 at 19:36
  • 4 "another DOM event" - does that other handler also create a new instance? – pimvdb Commented Feb 8, 2013 at 19:36
  • 3 Show us the code where you actually call customObj.method_2() – Explosion Pills Commented Feb 8, 2013 at 19:36
  • 2 Are those click handlers being bound inside the same $(document).ready handler? – gen_Eric Commented Feb 8, 2013 at 19:44
  • 1 @ParijatKalia: Then it should work, because it works for me: jsfiddle/bre7t – gen_Eric Commented Feb 8, 2013 at 19:47
 |  Show 7 more ments

2 Answers 2

Reset to default 3

The problem is that the scope in which you're setting var_1 to true isn't what you want it to be:

CustomClass.prototype.method_1 = function(){

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

You're setting var_ to true in a callback, and the value of this in the callback is not the same as in method_1.

You could use the self = this idiom to fix 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;
  };
}

That should solve your problem, though there is still a potential timing issue: if method_2 is called before the FileReader fires its onload event, var_1 won't yet be set to true.

this.var_1 is false, and not true as it should be.

That's likely because you do not refer to the same object. Your event handler function(){ var customObj = new CustomClass(…); } creates an instance and assigns it to a local variable. It will get garbage-collected once the function is ran.

IMO javascript is pass by reference, so that variable value should have been set to true in it's original place.

No, javascript is always pass-by-value. Yet, when you are passing objects, you are actually passing values that reference the object so there will be a lot of variables referencing the same "shared" object.

发布评论

评论列表(0)

  1. 暂无评论