3

I copied the code from YDKJS and the authors expected output is 'oops global', but when I run this in Node, I am getting 'undefined'. Why?

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo
};

var bar = obj.foo; // function reference/alias!

var a = "oops, global"; // `a` also property on global object

bar(); // "oops, global"
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Ramesh Kumar
  • 93
  • 1
  • 5
  • 1
    I didn't do any edit to the code, copied and saved as implicitLost.js and ran in terminal as 'node implicitLost.js' and got output as 'undefined' – Ramesh Kumar Nov 09 '17 at 17:22
  • Thanks for adding the info of how you were running it, Ramesh; it makes all the difference! :-) (I've edited it into the question.) – T.J. Crowder Nov 09 '17 at 18:14

1 Answers1

3

When you run your code in Node in the normal way:

node implicitLost.js

...Node runs your code as a module, not at global scope. The code shown there only outputs "oops, global" if it's run at global scope (for instance, in <script>...</script> in a browser). (Node also does this when you require(...) your code from another script.)

You can run your code at global scope by piping it into node instead of supplying it as an argument, using Node's REPL (note the < redirection):

node < implicitLost.js

Why it matters:

When run in a module, since the var a = "oops, globals"; is at module scope, it's only defined within that module; it doesn't become a global. So this.a in foo, which is trying to access a on the global object, doesn't see it.

Here's that code running at global scope:

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo
};

var bar = obj.foo; // function reference/alias!

var a = "oops, global"; // `a` also property on global object

bar(); // "oops, global"

And here it is running in an environment vaguely like the one Node runs it in:

(function() {
  function foo() {
    console.log(this.a);
  }

  var obj = {
    a: 2,
    foo: foo
  };

  var bar = obj.foo; // function reference/alias!

  var a = "oops, global"; // `a` also property on global object

  bar(); // "oops, global"
})();
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875