YDKJS - How 'this' working?

Viewed 150

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"
1 Answers

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"
})();

Related