I noticed that when passing an object's method (which updates one of the object's own properties) as an argument to another function, the original object will not be modified.
For example:
var obj = {
foo: 0,
bar: function () {
this.foo++;
}
};
function baz(callback) {
callback();
}
baz(obj.bar); // does not alter obj
obj.bar(); // increments obj.foo successfully
console.log(obj.foo); // should be 2, not 1
Why is this, since JavaScript objects are passed by reference?
This is because the context - or this
value - of a function is based on how it's called, not on how it's defined. Your bar
function doesn't know it's inside the obj
object.
When you do obj.bar();
, you are calling it in the context of obj
, thus this
is what you expect.
When you do baz(obj.bar);
, you are passing the bar
function as a parameter. It no longer has any ties to the obj
object. Remember, functions can be treated like variables. So, when baz
runs its callback, it's ran in the "global" context (this
is window
).
The solution here is to use .bind()
to "lock in" the this
value.
baz(obj.bar.bind(obj));