liveBook · Manning

This

As explained in Secrets of the JavaScript Ninja, Second Edition

The implicit JavaScript function binding whose value is determined by how the function is called.

A function can run with a different context than you expect. In JavaScript, `this` is an implicit value available inside a function: it identifies the context associated with that invocation. For ordinary functions, how you call the function matters more than where you defined it. section 4.1.2

Check the call before guessing the value of `this`:

  • Plain call, `fn()`: `this` is typically `window` in nonstrict browser code and `undefined` in strict mode. section 4.4
  • Method call, `object.fn()`: `this` is the object used for that call. The same function can therefore have different contexts when called through different objects. section 4.2.2
  • Constructor call, `new Fn()`: `this` is a newly created object that the function can initialize. An explicit object return replaces the constructed result; a primitive return does not. section 4.2.3
  • Explicit call, `fn.call(object, a, b)` or `fn.apply(object, [a, b])`: the first argument supplies `this`; the remaining arguments use different forms. section 4.2.4

One function, two contexts

`function context() { return this; }` can be assigned to both `first.getContext` and `second.getContext`. Calling `first.getContext()` returns `first`; calling `second.getContext()` returns `second`. Copying the function reference does not lock in its context. section 4.2.2

Listing 4.10. Binding a specific context to a function
<button id="test">Click Me!</button>                           #A
<script>
  function Button(){                                           #B
    this.clicked = false;
    this.click = function(){                                   #C
      this.clicked = true;
      assert(button.clicked, "The button has been clicked");   #D
    };
  }
  var button = new Button();                                   #E
  var elem = document.getElementById("test");                  #F
  elem.addEventListener("click", button.click);                #F
</script>

A click handler assigned from `button.click` does not necessarily run with `button` as `this`. When the browser invokes it for the HTML button, the state change lands on the event target rather than the backing object. section 4.2.4

For a callback that must keep its intended context, `button.click.bind(button)` creates a new function whose `this` stays bound to `button`; it does not change the original function. An arrow function takes `this` from its surrounding context instead. That helps when the arrow is created inside a constructor, but an arrow created in an object literal in global browser code takes the global `this`, not the object literal. section 4.3.2 section 4.3.1

How Secrets of the JavaScript Ninja, Second Edition covers it

How deep it goes
Works through four invocation forms and callback remedies, while deferring detailed event handling.
Examples
Contrasts calls through two objects and traces a click handler that updates the wrong object.
What it assumes
Assumes familiarity with functions, arguments, and object methods, but introduces `this` as an implicit function parameter.
What you can do after
Diagnose/debug with it when callbacks lose their intended context, then use `bind` or an appropriately placed arrow function.
How it connects
Connects function invocation to methods, constructor functions, event handlers, arrow functions, and `bind`.

Also explained in

Compare how 4 books explain this →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Secrets of the JavaScript Ninja, Second Edition. The section links point to the parts of the book it draws on.