46

When I type this in node.js, I get undefined.

var testContext = 15;
function testFunction() {
  console.log(this.testContext);
}
testFunction();
=>undefined

Without var keyword, it passes (=>15). It's working in the Chrome console (with and without var keyword).

EmptyArsenal
  • 6,518
  • 3
  • 28
  • 51
IGRACH
  • 3,036
  • 4
  • 26
  • 40

4 Answers4

57

It doesn't work in Node when using var because testContext is a local of the current module. You should reference it directly: console.log(testContext);.

When you don't type var, what happens is that testContext is now a global var in the entire Node process.

In Chrome (or any other browser - well, I'm unsure about oldIE...), it doesn't matter if you use var or not in your example, testContext will go to the global context, which is window.

By the way, the "global context" is the default this of function calls in JS.

gustavohenke
  • 38,209
  • 13
  • 113
  • 120
18

The key difference is that all modules (script files) in Node.js are executed in their own closure while Chrome and other browsers execute all script files directly within the global scope.

This is mentioned in the Globals documentation:

Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

The vars you declare in a Node module will be isolated to one of these closures, which is why you have to export members for other modules to reach them.

Though, when calling a function without a specific context, it will normally be defaulted to the global object -- which is conveniently called global in Node.

function testFunction() {
    return this;
}

console.log(testFunction() === global); // true

And, without the var to declare it, testContext will default to being defined as a global.

testContext = 15;
console.log(global.testContext); // 15
Community
  • 1
  • 1
Jonathan Lonowski
  • 112,514
  • 31
  • 189
  • 193
  • By "closure" and "scope" I think you mean "execution context". – RobG Nov 08 '13 at 02:37
  • @RobG They're still valid and commonly-used terms. But, yes, ECMA defines them as [Execution Contexts](http://www.ecma-international.org/ecma-262/5.1/#sec-10.3). – Jonathan Lonowski Nov 08 '13 at 02:48
  • They are commonly use incorrectly, some other references: [closure](http://jibbering.com/faq/notes/closures/#clClose), [scope](http://jibbering.com/faq/notes/closures/#clScCh) and [execution context](http://jibbering.com/faq/notes/closures/#clExCon). – RobG Nov 08 '13 at 09:26
  • @RobG I'm aware of what each are. But, the distinction is pedantic. Which is fine and I agreed with you about it. But, "*scope*" is still a valid term for describing the general concept while `[[Scope]]`, scope chains, and Execution Contexts are the more-specific implementation details. – Jonathan Lonowski Nov 08 '13 at 09:43
5

As mentioned in the document

var something inside an Node.js module will be local to that module.

So, it is going to be different as the var testContext is in module context and the context of this is global.

You can alternatively, use:

global.testContext = 15;
function testFunction() {
  console.log(this.testContext);
}
testFunction();
prasun
  • 6,324
  • 9
  • 33
  • 56
0

I believe the problem has to do with the this key word. If you do console.log(this) you will see that testContext is not defined. You may want to try:

this.testContext = 15;
function testFunction() {
  console.log(this.testContext);
}
testFunction();
Jason
  • 1,779
  • 15
  • 19