0

What is the value of this returned from an arrow function on an object literal when running in nodejs. This question was asked here however the answer is just not correct in nodejs. It is not global and it is not undefined in strict mode.

Here is the code snippet that I'm running:

"use strict";  // <-- Has no affect.
let a = {
  f: () => this
};

console.log(a.f())                          // {}
console.log(a.f() === global);              // false
console.log(a.f() === {});                  // false
console.log(a.f() === Object.create(null)); // false

Update:

Another way to illustrate what I'm seeing, run this at your command prompt:

node -e "let a = { f: () => this }; console.log( a.f() === global);"  // returns true

Now, copy the contents of the code in the string above into a script.js and run via:

node script.js  // returns false
Alex
  • 43
  • 4
  • Your comparisons to `{}` and `Object.create(null)` will never be `true` because a newly created object can never be the same as some other object, since they’re compared by reference. – Sebastian Simon Jul 15 '17 at 20:18
  • `a.f() === global` is [`true` for me](https://repl.it/J3bT). – 4castle Jul 15 '17 at 20:19
  • @4castle Interesting! Could you by chance run that in your local node and see if you get the same? – Alex Jul 15 '17 at 20:27
  • My local node is version 4.5.0 and has the same result. – 4castle Jul 15 '17 at 20:30
  • I just updated to version 8.1.4 and also get `true` for being the global object. – 4castle Jul 15 '17 at 20:37
  • Could this possibly be OS dependent? I was running the above code on MacOS with various node versions and get the above results on all versions. However, I just fired up a VM running lubuntu and node v4.2.6 and **a.f()** does return **global**. – Alex Jul 15 '17 at 20:39
  • @4castle are you on linux? – Alex Jul 15 '17 at 20:40
  • I was running it on Windows 10. I also just tried it on Ubuntu with v4.2.6 and got `global` again. It could just be on MacOS, but I don't have access to that. – 4castle Jul 15 '17 at 20:48
  • 1
    Something else odd. When I type the above code in the node REPL on MacOS, **a.f()** does return **global**. Running it via the node executable on both MacOS and Linux, it returns **{}**. – Alex Jul 15 '17 at 20:54
  • 1
    Value of `this` keyword is variable and depends on how a function is called. In case of arrow functions the function remembers the context in which it was defined. `this` in node modules seems to be a plain object. Also note that in JavaScript `{} !== {}` (2 different objects are not equal!) – Ram Jul 15 '17 at 22:07
  • @undefined What's a mystery to me though is that we're calling it in exactly the same way in both cases, yet, it yields **global** in one case and a plain object **{}** in the other. – Alex Jul 15 '17 at 22:32
  • That's because the the contexts are different. Your code effectively has no difference with `console.log(this)`. Your question actually should be: What does this refer to in local context of node modules. this seems to be a plain object. See the sandbox option of the following method of the vm module which is used by require for executing modules: https://nodejs.org/api/vm.html#vm_vm_runinnewcontext_code_sandbox_options. It says that the context will be a new object when there is no specified context. – Ram Jul 15 '17 at 22:46
  • @undefined Aha, **thank you**, this is starting to make sense to me now, let me see if I understand. So, in the REPL, it creates a `this` context (`global`) for you when you fire it up. But, when running via a script with just a `console.log(this)`, `this` has not been created yet hence node creates the empty object. This is why if you type `this` in the REPL you see `global` but if you run an script with a `console.log(this)`, you get a `{}`. Am I on the right line of thinking here? – Alex Jul 15 '17 at 23:29

0 Answers0