3

Given following code:

const theArray = ['Audi','Volvo','Mercedes'];

const myObj = {a: 7};

theArray.forEach((value, index, array) => {
    console.log(index + ' : ' + value);
    console.log(array === theArray);
    console.log(this.a);
}, myObj);

I get following output:

0 : Audi
true
undefined
1 : Volvo
true
undefined
2 : Mercedes
true
undefined

Where I don't understand why this does not reference myObj and returns undefined instead of 7. While this typeof Object returns true, I don't know which Object it references. I just know that this returns an empty Object(i.e. {})

Node.js interpreter version is v6.2.1

V8-Engine version is 5.0.71.52

MMike
  • 598
  • 3
  • 23
  • 2
    An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous. source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – Nina Scholz Jun 30 '16 at 15:37
  • It is working if you are removing the arrow function https://jsfiddle.net/t9sbfv5a/ – brk Jun 30 '16 at 15:38
  • @NinaScholz, What is the solution ? – Rayon Jun 30 '16 at 15:42
  • If you need to define thisArg you should use the older `function () {}` syntax. – MrWillihog Jun 30 '16 at 15:46
  • Arrow function always lexically bound to this. – Arnial Jun 30 '16 at 15:49

1 Answers1

8

Problem

Arrow functions:

An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous.

Solution 1

Use function

const theArray = ['Audi','Volvo','Mercedes'];

const myObj = {a: 7};

theArray.forEach(function (value, index, array) {
    console.log(index + ' : ' + value);
    console.log(array === theArray);
    console.log(this.a);
}, myObj);

Solution 2

Use a closure

var abc = 'abc';
const theArray = ['Audi','Volvo','Mercedes'];

const myObj = {a: 7};

theArray.forEach((obj => (value, index, array) => {
    console.log(index + ' : ' + value);
    console.log(array === theArray);
    console.log(obj.a);
    console.log(this.abc);
})(myObj));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Thanks, totally missed that point about arrow functions. So in my example, this refers to the object which encloses the forEach loop. (So this must be a/the global object which is just empty?) – MMike Jun 30 '16 at 16:36
  • `this` refers to the windows object. – Nina Scholz Jun 30 '16 at 16:45
  • 2
    Ok I think in node.js, there is no window object, maybe because it does run on the server and not in the browser. I found [this](http://stackoverflow.com/questions/19849136/does-node-js-have-equivalent-to-window-object-in-browser) which states that in node.js there is a Object global which is the closest to the window object. :) Just in case you are interested. – MMike Jun 30 '16 at 16:50
  • @MMike Node.js replaces the `window` with `process`. This acts as the global object with similar functionality to what you'd find in `window` on the browser. https://nodejs.org/api/process.html – Christopher Ronning Jul 02 '16 at 01:41
  • @ooronning `process` is not the global object like `window` is, `global` is. `process` is a global variable / property of `global` (and the `root` and `GLOBAL` aliases). – Alexander O'Mara Jul 02 '16 at 01:43
  • @AlexanderO'Mara Well then. Heh. Was totally unaware that `process` was a property of `global`. I was under the impression, though, that `process` takes on more of the functionality of `window`. Incorrect? – Christopher Ronning Jul 02 '16 at 01:48
  • 2
    @ooronning In some respects. The standard global JavaScript API's are available through `global`. `process` holds all the Node extensions. So you might think of it being like `document`, but it's really it's own thing. – Alexander O'Mara Jul 02 '16 at 01:51
  • @AlexanderO'Mara Thank you for your clarification. – MMike Jul 02 '16 at 09:16