I'm learning about the this identifier and I know that when a function is not called on an object then this refers to the window object in non-strict mode. As a result, I would expect this.bar to log "whatever."
"whatever" is the output when I run my code in the Chrome console.it, but the output is undefined when I run my code using the node build system in sublime.
Why is that the case? Am I right that the result in the Chrome console is correct? When else could I encounter problems like this?
Here's my code
function foo() {
// console.log(this)
console.log( this.bar );
}
var bar = "whatever";
// --------
foo(); // OUTPUT is "whatever" in the Chrome console and OUTPUT is undefined in Sublime's Node build system.
When you use this
in a function without specifying a different context, it refers to the global object. In Chrome, this will be the window
object. In Node, this is called global
. When I say specifying a different context, that would be, for example, using new
for a constructor, or the call
and apply
functions to bind a particular this
.
The main difference is that when you use var bar = "whatever";
in Node, the use of var
is scoping the variable to the module you are writing, not the whole Node process. In Chrome, you are scoping it to the global window
object. It is the same as leaving out the var
altogether.
I have added a couple of examples below regarding scope, just to make it a little clearer. Playing around in the Console is a great way to discover things like this.
Example 1:
As you can see, calling
test()
has created a globally scope x
variable, and this
is found to be referring to the window
variable.
Example 2:
In this example, we constructed a new instance, which creates a new scope. The
x
variable is not scoped globally. The only way to access it is to use the myInstance
context.
As for your problem, you have two options:
Option 1 (Recommended): Since bar is not globally scoped, you don't want to access the global variable using this
var bar = "whatever";
function foo() {
console.log(bar);
}
Option 2 (Not Recommended):
This will set the variable to be in global scope, so you can either use this
or global
global.bar = "whatever";
function foo() {
console.log(this.bar); // console.log(global.bar);
}