Binding Configuration
A confusing snippet:
function foo() {
var bar = "bar1";
baz();
}
function baz() {
console.log(this.bar);
}
var bar = "bar2";
foo(); // ???
Confusion occurs between lexical scope and dynamic scope (this
) People often want to make a cross between the two scopes. It is not possible. They are fundamentally different mechanism. We don't have a reference to our local context. It's a thing that exists, but we don't get reference to it. We cannot say that
this
should point to our lexical scope.Even on Stack Overflow, where the above snippet originates form (it's a distilled form) the wrong response received thousands of up votes and was accepted as the "right" answer. This shows that it's still very confusing for many people.
baz
is a utility function that we don't have control over, but it references this.bar
.The incorrect solution was:
// incorrect solution
function foo() {
var bar = "bar1";
this.baz = baz;
this.baz();
}
function baz() {
console.log(this.bar);
}
var bar = "bar2";
foo(); // ???
This solution is wrong, because the this
in foo
depends on the call site. The call site was the global object (rule #4) so this
still references the global scope. (in strict mode it would be undefined
). Adding to this,
baz
is already on the global object, so in the definition of foo
, this.baz
just points to the same global object property, like we have not had done anything. Point: no matter how hard you try, there's no way to cross over the
this
mechanism (dynamic scope) to lexical function scope.