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()).