JavaScript

Function.prototype.bind()メソッド

 編集:2022.08.12 by T.A.

指定の this 値と指定の引数を渡した関数を返します。

func.bind(thisArg[, arg1[, ...[, argN]]])
func Function
thisArg バインドされた関数が呼び出される際、this としてターゲット関数 func に渡される値です。

バインドされた関数が new 演算子によって構築された場合、この引数は無視されます。

bind を使用して setTimeout の中で(コールバックとして提供する)関数を生成する場合、thisArg として渡されたプリミティブ値はオブジェクトに変換されます。

引数が bind に提供されなかった場合、または thisArg が null または undefined であった場合は、実行スコープの this は新しい関数のための thisArg として扱われます。

argn 省略可func を呼び出す時、バインドされた関数に与えられる引数の前に付けて渡す引数。
戻り値

this の値と初期の引数を指定された関数のコピーです。

解説

bind() 関数は、新しいバインドされた関数、すなわち元の関数オブジェクトをラップする特殊関数オブジェクトexotic function object(ECMAScript 2015 からの用語)を生成します。バインドされた関数を呼び出すと、通常はラップされた関数が実行される結果になります。

バインドされた関数は、以下の内部プロパティを持ちます。

[[BoundTargetFunction]]
ラップされた関数オブジェクト
[[BoundThis]]
ラップされた関数を呼び出す時に常に this に渡される値。
[[BoundArguments]]
ラップされた関数を呼び出す時に、その要素が第1引数として使われる値のリスト。
[[Call]]
オブジェクトに関連する実行コード。関数呼び出し式を通じて実行される。内部メソッドへの引数は this 値と呼び出し式によって関数に渡される引数を含むリスト。

バインドされた関数が呼び出されると、内部メソッド [[Call]] を [[BoundTargetFunction]] 上で、Call(boundThis, ...args) の引数で呼び出します。ここで boundThis は [[BoundThis]]、args は [[BoundArguments]] で、その後に関数呼び出しで渡された引数が続きます。

バインドされた関数は new 演算子でも生成されます。これを行うとターゲット関数が代わりに生成されたようになります。与えられた this の値は無視され、追加された引数はエミュレートされた関数に提供されます。

バインドされた関数の生成
最もシンプルな bind() の使い方は、どのように呼び出された場合でも特定の this 値を持つ関数を生成することです。

初心者の JavaScript プログラマーがよくやる間違いは、あるオブジェクトからメソッドを取り出し、後でその関数を呼び出すとき、その内側の this 値が元のオブジェクトになると考えてしまうことです(例えば、そのメソッドをコールバック関数に使う場合)。

特に配慮しなければ、ふつうは元のオブジェクトが見えなくなります。その関数に元々のオブジェクトを bind() してバインドされた関数を生成すれば、この問題をきちんと解決することができます。

this.x = 9;    // 'this' はここではブラウザーのグローバルな 'window' オブジェクト
const module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX();
// 81 を返します

const retrieveX = module.getX;
retrieveX();
// 9 を返します。この関数はグローバルスコープで呼び出されるためです。

// 'this' を module に結びつけた新しい関数を生成
// 初心者のプログラマーはグローバル変数の x と
// モジュールプロパティの x とを混同するかもしれません。
const boundGetX = retrieveX.bind(module);
boundGetX();
// 81 を返します

¶省く

function Job(P1, P2){
  return this + ":" + P1 + ":" + P2
}
F=Job.bind(10, 20, 30); //=[function]:function () { [native code] }
D=F(); //="10:20:30"

テスト