Help us understand the problem. What is going on with this article?

jsのbindは意味がわからない

More than 1 year has passed since last update.

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

__mick
nodejs,coffee-script等で遊んでいます。 https://github.com/mick-whats
https://twitter.com/mick_x_
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away