so why inside foo(), "this.bar" gives undefined value but bar does
not.
Probably your var bar="bar";
is not actually in the global scope. If it was your code would work as shown. Referencing bar
will find a variable in any parent scope. But, this.bar
when this
is set to the global object requires a bar
that is defined in the global scope. So, we conclude that var bar="bar";
is not actually in the global scope.
When you make a normal function call and you are not running in strict
mode, this
will be set to the global object which is window
in a browser. In general, this is NOT a recommend use of this
and, in fact, it will break in strict
mode. But, I will explain what's going on in your code.
In your specific example, you can replace this
with window
and your code is essentially doing this:
function foo(){
window.baz = "baz";
log(window.bar + " " + baz);
log(bar + " " + baz); //bar baz
}
window.bar="bar";
foo();
// display output
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
And, here's the version when using this
:
function foo(){
this.baz = "baz";
log(this.bar + " " + baz);
log(bar + " " + baz); //bar baz
}
bar="bar";
foo();
// display output
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
And, as you can see, there is no undefined
value when you run either snippet.
If you run your code in strict
mode (which is highly recommended), then this
will be set to undefined
in a normal function call and your code will fail. Instead, only use this
when you know it has specifically been set to a value you want such as in a constructor function called with new
or in a method call or in a callback that is specifically setting this
to a known value (probably with .call()
or .apply()
).