JavaScript の bind は超絶便利なんだけど・・・
JavaScript には、「bind」というかなり便利なメソッドがあります。このメソッドを使うことで、this にまつわる良く有る問題をいい感じに解決できます。
thisではまるケース
var User = function (name) {
this.name = name;
}
User.prototype.printName = function() {// このメソッド内で使う this が曲者
alert('My name is ' + this.name);
}
var taro = new User('Taro');
taro.printName(); //「My name is Taro」と表示される
この場合、taro.printName() という形でコールしているので、printName() メソッド内の this は期待通り taro を指します。なので無事「My name is Taro」と表示されます。
ところが下のケースでは・・・
var User = function (name) {
this.name = name;
}
User.prototype.printName = function() {// このメソッド内で使う this が曲者
alert('My name is ' + this.name);
}
var taro = new User('Taro');
setTimeout(taro.printName, 1000);
1秒後に「My name is Taro」が表示されるかと思いきや、これだと「My name is undefined」と表示されてしまいます。
setTimeout に taro.printName を渡した時に、もはや taro の情報は引き渡されません。1 秒後に printName() がコールされる時には、taro と結びついてない状態でコールされます。なので printName() 内で this は taro を指しません!
bind で解決
setTimeout(taro.printName.bind(taro), 1000);
setTimeout() に関数を渡す時、taro.printName.bind(taro) とすることで解決。
1秒後に printName() をコールする際、ここで bind した taro オブジェクトに結び付けてコールしてくれます。この場合期待通り、printName() メソッド内の this.name は taro.name を指しますので、「My name is Taro」と表示されます。
全てのブラウザが対応してるわけではない
ただしこの超便利な bind()、全てのブラウザが対応しているわけではありません。
手元にあった数台のスマホで試してみても、半分くらいはこの bind() が実装されていません。