arrow function brokes this keyword #730

Closed
007lva opened this Issue Feb 9, 2015 · 10 comments

Projects

None yet

5 participants

@007lva
007lva commented Feb 9, 2015

this works:

work

This doesn't work:
notwork

why?

@kittens
Member
kittens commented Feb 9, 2015

Top level this is undefined ES6 modules as they're implicitly strict mode. Arrow functions inherit the outer this. Expected behaviour.

@kittens kittens closed this Feb 9, 2015
@kittens kittens added the invalid label Feb 9, 2015
@fkling
Contributor
fkling commented Feb 9, 2015

Put differently: If you want a function with its own this value, you cannot use an arrow function.

@kittens
Member
kittens commented Feb 9, 2015

Yeah, I phrased that terribly. Arrow functions aren't synonymous with normal functions. You can check out more about their usage here.

@developit

Summary: arrows are awesome

@007lva
007lva commented Feb 9, 2015

Oh, thank you very much, this is very instructive 😃

@dashed
Contributor
dashed commented Feb 21, 2015

@sebmck I'm wondering if babel can "warn" the user if this is transformed to undefined as s/he may unintentionally misused the arrow function? Which is likely the case...

@kittens
Member
kittens commented Feb 21, 2015

@Dashed I wish, #562.

@dashed
Contributor
dashed commented Feb 21, 2015

@sebmck Hmm. What about warning of the misuse of this within just arrow functions?

@kittens
Member
kittens commented Feb 21, 2015

@Dashed It would only catch the top level case and adding warning messages is a slippery slope.

@garthk garthk referenced this issue in hemanth/paws-on-es6 Mar 18, 2015
Closed

misleading arrow example #6

@ghost
ghost commented Apr 1, 2015

@007lva The value of this outside your arrow function is the same value of this at the top level which is undefined as ES6 is 'strict mode' by default.

If you try something like

function it () {
  $('#link').click(() => {
    let x = this.pathname;
  });
}

↓↓ look at what the transpiled output becomes

"use strict";

function it() {
  var _this = this;

  $("#link").click(function () {
    var x = _this.pathname;
  });
}

Arrow functions are bound to their outer function, that's what's cool about them, but if there is no wrapping function (like in your example) then the value will be undefined.

(...) thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be undefined:

"use strict";
function fun() { return this; }
assert(fun() === undefined);
assert(fun.call(2) === 2);
assert(fun.apply(null) === null);
assert(fun.call(undefined) === undefined);
assert(fun.bind(true)() === true);

That means, among other things, that in browsers it's no longer possible to reference the window object through this inside a strict mode function.

See here for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment