🫠
Function.prototype.bindを実装してみた(simple version)
Zennに同じ内容の文章が見つからなかったので書いてみた
題名通りに、bind
を実装する。
あればよい先行知識:
-
Function.prototype.bind
とは何か -
Function.prototype.apply
の使い方 - JSのPrototypeの理解
- JSの字句スコープに加えて、Closureの理解
- 関数とインスタンスメソッドが呼び出された時、中の
this
が参照する先
以上について全くピンと来ない方であれば、軽くZennの他の文章でポイント押さえてから次を読み進めることをお勧めします
Simple Version
Function.prototype.bind = function (context) {
const funcRef = this // 元の関数への参照に下のclosureが後ほどアクセスできるように
return function () {
return funcRef.apply(context, arguments)
}
}
解説
const funcRef = this
の意図は何か?と思ったら、実際bind
された関数を呼び出す時の状況を例に即して見てみましょう
// bindしたい関数の例
function getName() {
console.log(this.name)
}
const getNameBinded = getName.bind({name: 'ナナチ'})
getNameBinded() // ナナチ
最後から二行目に、関数たるgetName
がそのインスタンスメソッド.bind
を呼び出しているので、問題のthis
がここではgetName
を指すことになり、それをfuncRef
にキャッシュ。
続いて、closure = getName.bind({name: 'ナナチ'})
の実行は、以下のような「結果」をもたらすが
getNameBinded = function () {
return funcRef.apply(context, arguments)
}
その中、funcRef
とcontext
は、.bind
実行時のスコープにあるものを参照していて、参照先の値で置き換えると、つまりこれと同じ、
const getNameBinded = function () {
return getName.apply({name: 'ナナチ'}, arguments)
}
getNameBinded()を実行するときは... (本文主旨外なので割愛します)
たった六行の短いコードだが、中にはJSの文法の知識がいっぱい詰まってて、個人的には大好物です
最後に、ここまで読んでくださった方がいれば、是非2週間後とかもう一回実装してみましょう!何か新しい発見(おやっ)があるかも
もーちょっと小難しいバージョンもあるが、別の文章で書きたいと思います。
Discussion