New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arrow function brokes this keyword #730

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

Comments

Projects
None yet
5 participants
@007lva

007lva commented Feb 9, 2015

this works:

work

This doesn't work:
notwork

why?

@kittens

This comment has been minimized.

Show comment
Hide comment
@kittens

kittens Feb 9, 2015

Member

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

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

This comment has been minimized.

Show comment
Hide comment
@fkling

fkling Feb 9, 2015

Contributor

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

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

This comment has been minimized.

Show comment
Hide comment
@kittens

kittens Feb 9, 2015

Member

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

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

This comment has been minimized.

Show comment
Hide comment
@developit

developit Feb 9, 2015

Summary: arrows are awesome

developit commented Feb 9, 2015

Summary: arrows are awesome

@007lva

This comment has been minimized.

Show comment
Hide comment
@007lva

007lva Feb 9, 2015

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

007lva commented Feb 9, 2015

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

@dashed

This comment has been minimized.

Show comment
Hide comment
@dashed

dashed Feb 21, 2015

Contributor

@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...

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

This comment has been minimized.

Show comment
Hide comment
@kittens

kittens Feb 21, 2015

Member

@dashed I wish, #562.

Member

kittens commented Feb 21, 2015

@dashed I wish, #562.

@dashed

This comment has been minimized.

Show comment
Hide comment
@dashed

dashed Feb 21, 2015

Contributor

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

Contributor

dashed commented Feb 21, 2015

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

@kittens

This comment has been minimized.

Show comment
Hide comment
@kittens

kittens Feb 21, 2015

Member

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

Member

kittens commented Feb 21, 2015

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

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost 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.

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 subscribe to this conversation on GitHub. Already have an account? Sign in.