This question already has an answer here:
-
What does “this” mean in a nodejs module?
1 answer
The code
I write the following code and save it as test.js:
var foo = 'I am local';
global.foo = 'I am global';
function print () {
console.log(this.foo);
};
print();
console.log (this.foo);
I then run it in the terminal with the command node test.js
and it returns:
I am global
undefined
The question
Why does it not return:
I am global
I am global
?
Inside a Node module, this
by design refers to module's exports
object:
console.log(this === exports); // true
Making console.log(this.foo)
equivalent to console.log(exports.foo)
.
In other words, neither does this
refer to the global object nor do local variables magically become properties of exports
.
Since exports.foo
doesn't exist, you get undefined
.
All script files in Node.js are executed in their own execution context, while browsers execute all script files within the global execution context.
When calling a function without a specific context, it will normally be defaulted to the global object in Node.
print(); //global execution context -> 'I am global'
console.log (this.foo); // no context -> undefined
The this
property of a function is set when the function is called and by default points to the object calling the function unless the value is set by methods such as bind
, apply
or call
.
It is worth to note that a module (equivalent to a file) in Node is wrapped in a function() like this:
NativeModule.wrapper = [
‘(function (exports, require, module, __filename, __dirname) { ‘,
‘\n});’
];
This means that all the code snippets below are actually executed inside this wrapper function. See Where are vars stored in Nodejs for more detailed information.
Console.log(this) inside a function
The following code:
var apple = ‘red’; // private variable in the wrapper function
global.apple = ‘yellow’; // property on the global object
var foo = function () {
var apple = ‘green’;
console.log (this.apple);
}
foo();
returns yellow
because an inner function cannot access the this
value of any outer functions and in case of such inner functions it is standard behaviour of this
to default to the global object (the window object in browsers).
Console.log(this) inside an object
The following code:
var apple = ‘red’; // private variable in the wrapper function
global.apple = ‘yellow’; // property on the global object
var myObject = {
orange: ‘orange’,
print: function () {
console.log (this.orange);
console.log (this.melon);
}}
myObject.print();
returns orange
and undefined
because it is myObject
calling print
. It returns undefined
in relation to this.melon
, because myObject
has no property with the name melon.
Console.log(this) in module scope
The console.log
command is a property on Node´s global object with the value of a function and therefore you would expect the following code
global.apple = ‘yellow’;
global.console.apple = 'yellow';
console.log(this.apple);
to return yellow
as console.log()
is the same as global.console.log()
. This means that console.log()
is called by the global object and therefore you would expect this
to point to either global.apple
or global.console.apple
. However some of the functions on the global object is actually executed in module scope (see Global objects) and in this scope the designers of Node have chosen to set the value of this
to the object exports
, which is passed as a parameter to the function wrapping a Node module.
The above code therefore returns undefined
because exports
does not have a property with the name apple.