27
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Backbone.jsAdvent Calendar 2011

Day 7

コールバック関数内のthisを束縛する

Last updated at Posted at 2012-12-26

今回はBackbone.jsが依存するunderscore.jsに関する話題です。
Backbone.jsに限らず、JavaScriptではコールバック関数内でthisがグローバルのwindowを差してしまうため、この問題に対処するために、以下のようにthatやselfといった変数にthisを代入してコールバック内で使うということをすることがあると思います。

function () {
  var that = this;
  someFunc(function () {
    this; // window
    that; // 外側のthis
  });
}

これでもいいですが、若干面倒ですね。こんな時、ECMAScript5で導入されたbindを使えば

function () {
  someFunc(function () {
    this; // 外側のthis
  }.bind(this));
}

という風に書くことができますが、bindはブラウザによってはまだ実装されていなかったりするので、使うのを躊躇してしまいます。こういう時はunderscoreに定義されているbindを使えます。

function () {
  someFunc(_.bind(function () {
    this; // 外側のthis
  }, this));
}

##underscoreの便利関数を使う場合
underscoreにはbindだけでなくmapやforEachなどのECMA Script 5の関数を模倣した関数がいくつか定義されています。実際、これらは内部でネイティブで実装されていればそちらを使用し、なければJavaScriptで模倣するように実装されています。
で、たとえばmapを使う場合でも、コールバックにthisを渡すには上記の様なthatやbindを使う必要がありますが、これらのunderscoreの関数群は関数コンテキストを渡すことができます。言葉で説明するとよくわかりませんが、つまりこういうことです。

function () {
  _.map([1,2,3], function (s) {
    this; // 外側のthis
  }, this);
  _.map([1, 2, 3], function (s) {
    this; // window
  });
}

ここではmapを使用していますが、他の関数も同様にコールバック関数の次にコンテキストを渡すことができるので、上手に使えば、コードを綺麗に保つことができます。
もちろん、いかなる場合でもthatやselfを用いる、というのでも問題ないでしょう。

27
23
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?