When you use function
to define an anonymous function it's this
is not bound to the instance you defined it in, and jQuery leverages call
/apply
to give a value to this
inside of those callbacks.
The easiest solution is to swap to arrow functions:
$(this.element).on("change", () => {
this.Changed = true;
});
When you define an arrow function, the value of this
inside of the arrow function is tied to the value of this
in the scope the function is defined.
Another, less desirable alternative is the classic usage of that
or self
:
const self = this;
$(this.element).on("change", function() {
self.Changed = true;
});
EDIT
One final note, if you already have a function and can't use one of the above options for accessing the context of the outer scope, you can force this
to be what you want inside of a function using Function.prototype.bind
. This example is mostly relevant if your event handlers/callbacks are members of a class.
ChangeColor() {
$(this.element).on("change", this.HandleChange.bind(this))
}
HandleChange() {
this.Changed = true;
}
This only works with the call to bind
, if you forgot to bind it then you would end up with the same issue you started with. Also, binding on the fly like this can get costly as a new function has to be created every time bind
is called. So generally you pre-bind your functions you hand out in the constructor.
class RedTextBox {
constructor() {
this.HandleChange = this.HandleChange.bind(this);
}
ChangeColor() {
$(this.element).on("change", this.HandleChange);
}
HandleChange() {
this.Changed = true;
}
}
Notice how I only bind once in the constructor and then I freely pass the reference to this.HandleChange
as the callback.