Question 17 / 31

Why does calling the same function two ways log two different values?

Topic: this bindingDifficulty: Foundation

this is determined entirely by the call-site syntax, not by where the function was defined.

Solve it with the execution visualizerStep through every binding, function call, and console output below.

Predict the output

Predict both lines. obj.foo() and foo2() invoke the very same function object — why do they disagree?

function foo() {
  console.log(this.a);
}
var obj = { a: 1, foo };
var a = 2;
var foo2 = obj.foo;

obj.foo();
foo2();
Reveal the answer and explanation

Expected output

1
2

Why this happens

foo is declared once, then attached to obj as a property. Calling obj.foo() is a member-expression call, so implicit binding sets this to obj, and this.a reads 1.

foo2 is a plain variable holding a reference to the very same function object, with no receiver attached to the call syntax.

Calling foo2() is a receiver-less call, so default binding applies and this resolves to the global object, whose a property was set to 2 by the earlier var a = 2, giving 2.

What this question tests

  • this binding is decided at the call site, not at the function's definition site
  • implicit binding wins when a function is invoked as obj.method()
  • detaching a method into a bare variable strips away implicit binding

Runtime assumptions

Assumes a classic sloppy-mode script, where a top-level var also creates a property on the global object that default binding can read.

Specification references

JavaScript Code EditorDirectly edit or paste custom code
Step 0 of 0
StepSpaceRun
Press → (Step) or Space (Run)
Phase 1: Compilation(Hoisting & Memory Setup)
Phase 2: Execution(Line-by-line Evaluation)
Execution Step Breakdown

Press "→" / click "▶" to step line-by-line, or press "Space" / click "▶ Run" for auto-play.