2
// example A (works)
foo(function() {
    myObj.save();
});

// example B (doesn't work)
foo(myObj.save);

// example C (works)
foo(myObj.save.bind(myObj));

Why is the this reference correct when myObj.save is called in example A, but not in example B?

I can force this to be correct by using bind, but what is happening in example A that is different from example B?

I don't understand why this would be different.

Reactgular
  • 52,335
  • 19
  • 158
  • 208
  • Because current method for object can change. This pattern is called signal pattern. You giving current implementation of function but in other place it can be change by other method or function. This method / function can't be use also by other object so making it contextful create new function (with owner) object. And this why you need to bind it. For performance reason this is made only on demand. – Eraden Jan 25 '15 at 16:39

2 Answers2

2

Functions only have a context, this, when invoked.

When you call x.y(), the this context inside y is x.

When you write x.y, you're referencing just the function y, you're not invoking it and there is no context. When you pass that function elsewhere, such as z = x.y, the context is not passed with it.

You're doing that in your second example. You're passing the function without context into foo, where there is no possible way for foo to know what the context should be. When it's invoked by foo, it's going to be invoked a simple save() call, and when this happens the this context will be window (or null in strict mode).

user229044
  • 232,980
  • 40
  • 330
  • 338
1

This is because this refers to the object on which a method was called. When you set the method of a function to a variable, or pass it in as an argument, it is no longer associated with the object it was a method of.

Multiple objects can share the same function, this is a way of dynamically reusing that function to manipulate the object instance it is a method of.

The bind method was added later to address use cases such as these.

Alexander O'Mara
  • 58,688
  • 18
  • 163
  • 171