POSTD PRODUCED BY NIJIBOX

POSTD PRODUCED BY NIJIBOX

ニジボックスが運営する
エンジニアに向けた
キュレーションメディア

POSTD PRODUCED BY NIJIBOX

POSTD PRODUCED BY NIJIBOX

ニジボックスが運営する
エンジニアに向けた
キュレーションメディア

FeedlyRSSTwitterFacebook
Partial Application in JavaScript using bind()

著者プロフィール非公開

本記事は、原著者の許諾のもとに翻訳・掲載しております。

JavaScriptの中にはコードをもっとシンプルで見やすくできるパターンがあるのに、あまり使われていないものがあります。皆さんも Function.prototype.bind はご存じでしょう。頻繁に使われていた var that = this var self = this の代わりになる関数です。よくあるのが以下のような例です。

this.setup = function () {
   this.on('event', this.handleEvent.bind(this));
};

第1引数が bind (束縛)され、返される関数内で this として働きます。あまり知られていませんが bind は複数の仮引数を取ることができ、 bind された関数が呼び出されると bind される後続のすべての仮引数は、その仮引数リストの前に付加されます。

つまり以下のように、関数を部分適用することができるのです。

var add = function (a, b) {
  return a + b;
};
var add2 = add.bind(null, 2);
add2(10) === 12;

すごいでしょう。冒頭に例として挙げたイベント処理コードを拡張する場合など、この利点がよく分かります。他にもイベント処理の一般的なパターンとしては、ハンドラを呼び出す時にコンテンツを指定するというのがあります。

this.setup = function () {
  this.on('tweet', function (e, data) {
    this.handleStreamEvent('tweet', e, data);
  }.bind(this));
  this.on('retweet', function (e, data) {
    this.handleStreamEvent('retweet', e, data);
  }.bind(this));
};

仮に tweet retweet のイベントハンドラが似かよった論理構造の場合、このようにコードを書くのもいいでしょう。ただし欠点は一目瞭然で、ボイラープレートコード(似ているのに省略できないお決まりのコード断片)だらけです。両方に無名関数を用意しなければなりませんし、それぞれ内部でイベントハンドラを呼び出して引数を受け渡し、関数を bind して this コンテキストをきちんと設定しないといけません。

もう少しシンプルにできないものでしょうか? もちろんできますよ。

this.setup = function () {
  this.on('tweet', this.handleStreamEvent.bind(this, 'tweet'));
  this.on('retweet', this.handleStreamEvent.bind(this, 'retweet'));
};

これならスッキリしますね。無名関数内で関数を呼び出す代わりに部分適用された関数を2つ用意し、thisコンテキストとそれぞれ異なる第1仮引数を両方に指定しました。もちろん e data も問題なく渡されます。

もし皆さんが数カ月前の私と同じなら、ショックで自分の書いたコードから似たような箇所を探してきてはクリーンアップしたくなることでしょう。その作業が終わったら、このことを友達にも教えてあげてください。

監修者
監修者_古川陽介
古川陽介
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
複合機メーカー、ゲーム会社を経て、2016年に株式会社リクルートテクノロジーズ(現リクルート)入社。 現在はAPソリューショングループのマネジャーとしてアプリ基盤の改善や運用、各種開発支援ツールの開発、またテックリードとしてエンジニアチームの支援や育成までを担う。 2019年より株式会社ニジボックスを兼務し、室長としてエンジニア育成基盤の設計、技術指南も遂行。 Node.js 日本ユーザーグループの代表を務め、Node学園祭などを主宰。