ひとりSE

ひとりでシステム開発やってます。真面目な業務システムからふざけたゲームまで

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() が実装されていません。