Why Does Javascript "this" Returns Different Values In Node And Browser Environments?
Solution 1:
In node.js, your bar
variable is a module variable which is local to that module. It is not a global variable. Globals in node must be explicitly assigned to the global
object. Top level declarations in a node.js module are not automatically globals like they are in a browser JS file. Technically, they exist inside a function scope that is created by the module loader so they are local variables to the module's function scope.
In node.js, the value of this
in a plain function call like foo()
is the global
object.
But, in node.js, your bar
variable is NOT a property of the global object. So, when you try to reference this.bar
, that's global.bar
and there is no property on the global object by that name.
So, in node.js, you're essentially doing this:
// create a function which is like the module scopefunctionmyModuleFunc() {
functionfoo() {
// the value of this in a plain function call in node.js is the// global objectconsole.log(global.bar);
}
// this isn't a globalvar bar = "bar1";
foo();
}
// execute that module scope functionmyModuleFunction();
And, hopefully you can see why there is no global.bar
property, thus you get undefined
.
This all accidentally works in a browser because var bar
is a global and globals are on the window
object and this === window
so it accidentally works. Two wrongs make a right that works only sometimes.
As I said in my comment, it is highly recommended to run your code in strict mode and things will not accidentally work sometimes, but not others - this issue will all be highly consistent and you will get an immediate error when you have written the wrong sort of code.
Though you said you already understand what is happening in the browser environment, since your question asks why the two are different, I will describe the browser situation just to cover all the bases.
In the browser, the value of this
in a plain function call (when not in strict mode) is the window
object.
In the browser, your bar
variable is a global variable and thus automatically becomes a property of the window
object.
So, in the browser, you are essentially doing this:
functionfoo() {
console.log(window.bar);
}
window.bar = "bar1";
foo();
And, thus you can see why it happily creates a property on the window
object and then references it.
Solution 2:
That is because of the variable declaration var bar = "bar1";
, That is declared in the global scope. All global variables are available as properties of the window object.
When you call foo()
without any context the default context of the method is the window
object(in non strict mode), so your code execution becomes console.log(window.bar);
, as we have seen above your bar
variable has attached itself to the window object as a property, so its prints the value bar1
functionfoo() {
snippet.log('is window:' + (thisinstanceofWindow))
snippet.log('bar value: ' + this.bar);
}
var bar = "bar1";
snippet.log('window.bar: ' + window.bar)
var obj = {
bar: "bar2"
};
foo();
foo.call(obj);
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --><scriptsrc="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Post a Comment for "Why Does Javascript "this" Returns Different Values In Node And Browser Environments?"