Reactのドキュメントで出てきた疑問だが、ReactというよりもむしろJSの知識だ。
同期に教わってみると意外とシンプルだった。bindは何かというよりも、むしろ本当の問題は「thisとはなにか」というところにある。thisは実行時のコンテクスト[note]スコープのようなもの?難しい[/note]であって、関数を呼ぶ方法によって変化する。
class MyClass {
getX() {
return this
}
}
const myclass = new MyClass()
// クラスから呼び出すと、想定通りに動く
console.log(myclass.getX())
// MyClass{}
// 一度関数単体で取り出してしまうと、thisがなんだったか忘れてしまう
const unboundGetX = myclass.getX
console.log(unboundGetX())
// undefined
// bindを使うとthisを指定しながら関数を実行できる
const boundGetX = myclass.getX.bind(myclass)
console.log(boundGetX())
// MyClass{}
筆者はPythonを先に学んでいたのでJSの上記の仕様には違和感があった。しかしPythonのクラスのメソッドは常にselfを引数に取る(必ずselfが第一引数として渡される)一方でJSはそうではない。どちらも意図的なデザインなのだろう。
class MyClass:
def getX(self):
return self
myclass = MyClass()
# クラスから呼び出すと想定通り動く
print(myclass.getX())
# <__main__.MyClass object at 0x7f2a12223588>
# 関数単体で取り出しても想定通り動く
unboundGetX = myclass.getX
print(unboundGetX())
# <__main__.MyClass object at 0x7f2a12223588>
厳密な話を知りたい人はこの辺読んでください。アロー関数の話もしたいね。