13

I have the following ES6 code using a fat arrow function:

var test = {
  firstname: 'David',
  fn: function() {
    return ['one', 'two', 'tree'].map(() => this.firstname)
  }
}
console.log(test.fn())

According to how arrow functions are supposed to work I'd expect this to be the test object. ES6Fiddle, Traceur and Firefox produce the expected output which is ["David", "David", "David"].

When enabling those features in Chrome using chrome://flags/#enable-javascript-harmony, however, I get [undefined, undefined, undefined]. If you console.log(this) it shows that it is the window object and you get an error in strict mode. Is the lexical this for ES6 arrow functions not implemented in V8 yet?

hippietrail
  • 15,848
  • 18
  • 99
  • 158
Daff
  • 43,734
  • 9
  • 106
  • 120
  • 1
    Works just fine in FF. I guess Chromes implementation is still sloppy there. – jAndy Jan 19 '15 at 16:43
  • 2
    From November last year: https://code.google.com/p/v8/issues/detail?id=2700#c28 – Felix Kling Jan 19 '15 at 16:47
  • 5
    Yep, `this` binding in arrow functions is Chrome's biggest issue right now. On our test in compat table it only implements 4 out of 9 — http://kangax.github.io/compat-table/es6/#arrow_functions – kangax Jan 19 '15 at 17:36
  • Thanks @kangax, should have looked it up there right away! Good to know - too bad it makes arrow functions way less useful in V8. – Daff Jan 19 '15 at 19:56
  • :( Same problem in Node 0.12 with `--harmony` flag. – Jorge Bucaran Apr 29 '15 at 18:22
  • My understanding had been that the context of an arrow function would always come from the *scope* where it was defined; that is, its `this` is whatever `this` is right outside it. But if the above should output Davidx3, I was wrong -- which, on further investigation, I was. So I'm commenting in case someone in my boat comes by and is similarly baffled. It seems arrow functions assume their scope's context *except when defined inside an object literal* in which case they assume the object as their context. This is useful of course, but I'd never gotten the memo. Is that accurate? – Semicolon May 12 '15 at 16:12

2 Answers2

11

Lexical this is the last part of ES6 arrow functions to land in v8 and it is the reason why it is still behind a flag and not ready to ship yet. Adrian Perez at Igalia is implementing arrow functions and the final patch is almost ready to land as soon as a few TurboFan issues are worked out: https://codereview.chromium.org/883823002/

Andrew Paprocki
  • 273
  • 2
  • 5
  • It seems that arrow function was shipped in Chrome 45.0.2429+ under the "chrome://flags/#enable-javascript-harmony" flag. http://wingolog.org/archives/2015/06/18/arrow-functions-coming-to-chrome-45#comments – Alexandr Skachkov Jun 28 '15 at 21:28
  • @AlexandrSkachkov thanks Cpt. Obvious. But how is this helpful to the above issue that arrow functions not seem to bind to the lexical this in class methods under V8? – kernel Jul 02 '15 at 14:39
  • 1
    @kernel, arrows shipping implies that their implementation has been completed, so the issue no longer exists. – Andreas Rossberg Jul 03 '15 at 05:42
  • 1
    @AlexandrSkachkov, in fact, arrows will be available in upcoming Chrome 45 even without the flag. – Andreas Rossberg Jul 03 '15 at 05:42
  • @kernel Sorry for not full answer. I mean it was shipped so all issues with lexical this were fixed. Script from question works as expected in my Chrome Canary. Also article from link is said about shipping arrow function and fixing issue with lexical 'this' – Alexandr Skachkov Jul 03 '15 at 13:57
  • 1
    Thanks @AlexandrSkachkov. Last thing to find out is, when this exact V8 version from Chrome 45 lands in node / iojs. Currently they are merging V8 v4.5.89, but I don't know much about whats behind this version. Chrome 43 seems to have V8 4.3.61.30 installed so it looks like the Chrome Version is coherent with the major and minor version of the V8's versioning. With that in mind Chrome 45 should implement V8 v4.5.x and the issue should be solved when https://github.com/nodejs/io.js/pull/2091 is merged. – kernel Jul 06 '15 at 10:24
  • 1
    In the meantime this pull request is closed and will be available in the io.js next+1. – kernel Jul 15 '15 at 11:48
  • @kernel Update: io.js 2.4.0, V8 4.2.77.20 -- it still does not work. – Mörre Jul 18 '15 at 13:18
  • 1
    @MörreNoseshine as mentioned this is solved in V8 4.5+. This will likely need some time to land in iojs as a tag. – kernel Jul 18 '15 at 15:38
  • This will be shipped with the next major version of both Chrome and io.js, so Chrome 45 (due for release in september) without flags, as Andreas pointed out, and io.js 3.0 (next+1) as kernel pointed out. If io.js gets merged with node before this point they will ship is as node 0.13, but this is not likely. – Albin Jul 20 '15 at 14:19
1

The fat arrow is a feature of ES6. It's been introduced in Firefox(Gecko) but not yet in other browsers (and especially not completely in V8 which would be interesting for nodejs/iojs development).Here is a reference doc

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Browser_compatibility

Anyways If you need the scope binding, then instead of => use bind(). Here is a simple example.

Instead of this.

$("#example").on("click", () => {
   // your code goes here
});

Use this.

$("#example").on("click", (function() {
   // your code goes here
}).bind(this));

If you don't need the scope binding then simply do so.

$("#example").on("click", function() {
   console.log("example");
});
Nikhil Nanjappa
  • 6,454
  • 3
  • 28
  • 44