babelでES6を変換するとthisがundefinedになっちゃう問題

Tsukasa OISHI

ECMAScript2015 (ES6) を最近触りだしたのですが、既存のコードを置き換えていていきなりつまづきました。

$("aside.socialButton").each(() => {
  const articleId = $(this).data("articleId");
});

上のコードをbabelにかけて変換すると、下のようになりました。

$("aside.socialButton").each(function () {
  var articleId = $(undefined).data("articleId");
});

あれ? なぜか $(this)$(undefined) になっています。
しばらく悩んでいたのですが、babelのGithub issueにいくつもこの話題が出ていました。 ( https://github.com/babel/babel/issues/730 など)
babel のサイトのFAQにも出ています。( http://babeljs.io/docs/faq/#why-is-this-being-remapped-to-undefined- )

arrow function内のthisは、関数が定義されたコンテキストのthisにバインドされるようです。
これは var self = this; みたいなことをやっていたベストプラクティスが不要になるので基本的には歓迎なのですが、今回のようなケースでは困ることになります。

てっとり早いのはarrow functionをやめることです。

$("aside.socialButton").each(function(){                                                                                                                                                                  
  const articleId = $(this).data("articleId");
});

ぼくは arrow functionをやめるのも嫌なので、thisを書かなくていいようにしました。

$("aside.socialButton").each((i, ele) => {
  const articleId = $(ele).data("articleId");                                                                                                                                                             
});