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
2Why 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.