Call-site

To understand this binding, we have to understand the call-site: the location in code where a function is called (not where it’s declared). We must inspect the call-site to answer the question: what’s this this a reference to?

Finding the call-site is generally: “go locate where a function is called from”, but it’s not always that easy, as certain coding patterns can obscure the true call-site.

What’s important is to think about the call-stack (the stack of functions that have been called to get us to the current moment in execution). The call-site we care about is in the invocation before the currently executing function.

Let’s demonstrate call-stack and call-site:

  1. function baz() {
  2. // call-stack is: `baz`
  3. // so, our call-site is in the global scope
  4. console.log( "baz" );
  5. bar(); // <-- call-site for `bar`
  6. }
  7. function bar() {
  8. // call-stack is: `baz` -> `bar`
  9. // so, our call-site is in `baz`
  10. console.log( "bar" );
  11. foo(); // <-- call-site for `foo`
  12. }
  13. function foo() {
  14. // call-stack is: `baz` -> `bar` -> `foo`
  15. // so, our call-site is in `bar`
  16. console.log( "foo" );
  17. }
  18. baz(); // <-- call-site for `baz`

Take care when analyzing code to find the actual call-site (from the call-stack), because it’s the only thing that matters for this binding.

Note: You can visualize a call-stack in your mind by looking at the chain of function calls in order, as we did with the comments in the above snippet. But this is painstaking and error-prone. Another way of seeing the call-stack is using a debugger tool in your browser. Most modern desktop browsers have built-in developer tools, which includes a JS debugger. In the above snippet, you could have set a breakpoint in the tools for the first line of the foo() function, or simply inserted the debugger; statement on that first line. When you run the page, the debugger will pause at this location, and will show you a list of the functions that have been called to get to that line, which will be your call stack. So, if you’re trying to diagnose this binding, use the developer tools to get the call-stack, then find the second item from the top, and that will show you the real call-site.