0

Don't know if the question's title is too confusing but here I go.

If I got something like:

var Test = function(){
    this.foo = a;
}

Test.prototype.init = function() {
    $(document).on('change', '.form-control', this.myFunction);
}

Test.prototype.myFunction = function() {
    console.log(this.foo);
    console.log(this);
}

My understanding is that when printing 'this' in myFunction it would print the execution context of the function that made the call, in this case it'll print the execution context for .on('change' ...). So when printing this.foo since it doesn't exist in that context then undefined will be printed out.

To solve this issue and to access this.foo, I'm doing the following:

Test.prototype.init = function() {
    $(document).on('change', '.form-control', (this.myFunction).bind(this));
}

Test.prototype.myFunction = function() {
    console.log(this.foo);
    console.log(this);
}

I'm binding 'this' to the function call, so this.foo would be printed out which is OK, but my question is, in that case how can I also get access to the execution context for .on('change' ...)??? Meaning, how can I access the 'this' that I had originally access to before the binding?

Thanks

Sebastian
  • 845
  • 4
  • 12
  • 25

2 Answers2

0

Instead of binding, just use a reference variable. It will maintain the context, and still allow you to use the .on's context with this

Test.prototype.init = function () {

    var context = this;

    $(document).on('change', '.form-control', function () {
        context.myFunction();
        console.log(this); // `this` has context to the onchange
    });
};
KevBot
  • 17,900
  • 5
  • 50
  • 68
0

A bound function's this will always be bound to that same value. That means you no longer have access to the "original" value.

If you want to use both thises, you'll have to use one as this and the other as an argument. Or both as arguments.

var Test = function(a) {
  this.foo = a;
  this.init();
}

Test.prototype.init = function() {
  // Set `this` to the calling test object, and window
  // (which would be the original context in this case)
  // as first parameter of `myFunction`. Swap the arguments
  // if you wish to use them the other way around.
  window.setTimeout(this.myFunction.bind(this, window), 500);
};

Test.prototype.myFunction = function(that) {
  console.log(this.foo);
  console.log(that.foo);
};

new Test(5);

Btw, ES6 arrow functions keep the environment they're defined in, meaning that this would point to your test object.

Test.prototype.init = function() {
  window.setTimeout(() => this.myFunction(window), 500);
};
pishpish
  • 2,574
  • 15
  • 22