Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - Object State

I may be approaching this incorrectly...

I'm trying to keep track of an objects state internally and use it to call modified methods:

createObject = function() {
  this.a = 1

  this.method1 = function() {
  if (this.a == 1 ) {
    //do stuff
    this.a = 0
  }
}

var x = new createObject()

Unfortunately, state isn't being internally tracked. If I change the properties of another object it works perfectly however:

otherObj = { a:1 }

createObject = function() {

  this.method1 = function() {
  if (this.a == 1 ) {
    //do stuff
    otherObject.a = 0
  }

}

var x = new createObject()

Is this the correct way to approach this?

like image 996
Jamie S Avatar asked Dec 12 '22 10:12

Jamie S


1 Answers

You have problem, because this in method1() is different from this in outer function. That's because in JS functions create scope.

First approach

So you might want a to be a variable, not a property of this:

createObject = function() {
  // 'a' is now available here...
  var a = 1

  this.method1 = function() {
    // ... and here as well.
    if (a == 1 ) {
      a = 0
    }
  }
}

Second approach

Alternatively, you might want to hold a reference to the outer this in a helper variable (called self in this example):

createObject = function() {
  // 'self' is a regular varialbe, referencing 'this'
  var self = this;
  this.a = 1

  this.method1 = function() {
    // Here, self !== this, because 'this' in method1() 
    // is different from 'this' in outer function.
    // So we can access 'self.a':
    if (self.a == 1 ) {
      //do stuff
      self.a = 0
    }
  }
}

Third approach

Finally, you can also use bind() to tie outer this to your method1():

var createObject = function () {
    this.a = 1

    this.method1 = function () {
        console.log(this.a);
        if (this.a == 1) {
            this.a = 0
        }
    }.bind(this);
    // ^ note `bind(this)` above. Now, 'this' inside 'method1'
    // is same as 'this' in outer function.
}

Here is a doc for bind(). Note that it's not available in IE < 9.

like image 107
kamituel Avatar answered Dec 28 '22 11:12

kamituel