The Value of `this` When Calling Functions in JavaScript

There are three different ways to call functions in JavaScript, and they have different implications for the value of this.

  1. Function style
  2. foo();
  3. this is set to the global scope (usually window).
  4. Method style
  5. obj.foo();
  6. this is set to the object on which the method is called.
  7. Constructor style
  8. new foo();
  9. this is set to the new instance that is being created.

A common pattern in JavaScript is to use callbacks. A callback is a function passed to another function. The callback will be invoked inside that outer function whenever the outer function is invoked.

Callbacks are usually invoked via function style. If you pass in an object's method as a callback, it will be invoked via function style, and its this value will point to the global scope. This is a problem if your object's method relied on this pointing to the object!

Even if you pass in the object via dot notation, you are just passing in a function object. You're not invoking the function via method style. The dot notation simply points you to the correct function object, which can then be invoked in any style.

var foo = {
  greeting: "hello",
  
  yellGreeting: function () {
    console.log(this.greeting + "!");
  }
};

function times(num, func) {
  for (var i = 0; i < num; i++) {
    func(); // method is invoked 'function style'
  }
}

times(3, foo.yellGreeting); //prints "undefined!" 3 times

You can solve this problem by using bind. Call bind on a method to manually set the value of this inside of it.

times(3, foo.yellGreeting.bind(foo)); //prints "hello!" 3 times

The methods apply and call are similarly used to set the value of this, but they can also pass arguments into the function. apply accepts a single array of the arguments to pass, whereas call accepts each argument individually.