jsのbindは意味がわからない。
bind() メソッドは、呼び出された時に新しい関数を生成します。新しい関数が呼び出される時、this キーワードは与えられた値がセットされ、ます。2 個目以降の引数は、新しい関数より前に、ターゲット関数の引数として与えられます。
Function.prototype.bind() - JavaScript | MDN
「引数をbind(拘束)した新しい関数を作れる」という事はわかったけど、それ何が嬉しいの?と思っていた。
しかし先日、ある出来事をきっかけに理解することができたのでポエムを書いてみる。
この物語はフィクションです。登場する人物はすべて架空のもので(略
私はmodule(もしくはpackage)の開発者。githubを通じて便利な関数を公開している。
先日もredCharacter
という超絶便利な関数を公開した所だ。
// java script
var redCharacter = function(val) {
if (val >= 0) {
return val;
} else {
return `<span style="color:red;">${val}</span>`;
}
}
# coffee script
redCharacter = (val)->
if val >= 0
return val
else
return "<span style=\"color:red;\">#{val}</span>
見ての通り、引数の数字がマイナスなら赤字を返すという関数だ。
「赤字はdeficitだろ」というクレームはともかく、他にも要望が入った。
「文字色がredはドギツいので#CC0000
くらいがいい」「いや#990000
だ」「閾値はゼロ以外にも設定したい」などなど。
仕方がないので仕様を変えてみた。
// java script
redCharacter = function(val, color) {
color = color || 'red';
if (val >= 0) {
return val;
} else {
return `<span style="color:${color};">${val}</span>`;
}
}
# coffee script
redCharacter = (val, color)->
color = color or 'red'
if val >= 0
return val
else
return "<span style=\"color:#{color};\">#{val}</span>
公開して数日、プルリクエストが来た。
はじめまして、こんにちは。
あなたの作ったredCharacterを使わせていただいています。とても便利です。
しかし私のプロジェクトでは赤字を#CC0000
に統一しています。なのでredCharacter(-100, '#CC0000')
といちいち色指定するのは不便です。
そこでbindできるように書き換えてみました。良ければPullお願いします。
ソースコードは以下のようになっている。
// javascript
redCharacter = function(val) {
var color, threshold;
color = (this != null ? this.color : void 0) != null ? this.color : 'red';
threshold = (this != null ? this.threshold : void 0) ? this.threshold : 0;
if (val >= threshold) {
return val;
} else {
return `<span style="color:${color};">${val}</span>`;
}
}
# coffee script
redCharacter = (val)->
color = if @?.color? then @color else 'red'
threshold = if @?.threshold then @threshold else 0
if val >= threshold
return val
else
return "<span style=\"color:#{color};\">#{val}</span>
使い方は以下。
文字色がred
で良ければそのまま使える。
redCharacter(-100)
// '<span style="color:red;">-100</span>');
文字色を変えたければbindして新しい関数を作る。
新しい関数は文字色を#CC0000
に拘束してあるので、引数を都度指定する必要が無い。
var newRedCharacter = redCharacter.bind({color: '#CC0000'})
newRedCharacter(-100)
// '<span style="color:#CC0000;">-100</span>'
newRedCharacter(100)
newRedCharacter(-20)
// 当然ながら何度でも使える
ちなみに、呼び出しが1回限りなら以下の方法でも良い。
redCharacter.call({color: 'pink'}, -100)
// '<span style="color:pink;">-100</span>'
そんなわけでbindとは「引数をbind(拘束)した新しい関数を作れる」関数である。
繰り返し使うカスタム関数を手軽に生成できるのが便利。
おまけ
qiitaのmarkdownって色記号をバッククオートで括るとサンプル色見られるんすね。
#ddd
#123
#f90