gorogoronyan FC2

this の指す内容に注意、bind() のサンプル

概略

2022年追記: bind() はアロー関数に置き換えられます

bind() も IE 時代までの昔話になっています。

IE を気にしない JavaScript (ES2015 以降) では アロー関数 を多用します。 アロー関数を使うと this が何を指してるかの面倒な話がなくなるので bind() を書く必要がなくなります。 また、引数の末尾に event が自動的に付くといった暗黙の話もなくなります。

概略

JavaScript でイベントリスナーの処理をしたり、 class のオブジェクトを作ってクラス内の関数 (メソッド) を this.関数名() で呼び出すときに、 しばしば関数が見つからないエラー (undefined で TypeError) が起こることがあります。 this の指しているオブジェクトが異なるため発生します。 このようなときには関数を呼び出す側で this が何を指しているのか bind() で指定します。

Java や C# のクラスやメソッドや this の使い方に慣れている人も必ずはまる話なので 参考にどうぞ。同じ感覚で扱おうとしたら必ず泥沼にはまります・・・。

this 違いでエラーが起こる

JavaScript では this の意味が Java や C# と異なります。 処理がどのように呼び出されたか状況に応じて this の指しているオブジェクトが変わることがあります。IE 時代までの JavaScript では this が何を指すかを明示するときに bind() を 使用していました。

近年はアロー関数を使うと bind() による明示が不用になります。 また、this を気にする話が大幅に減ります。
アロー関数: 「アロー関数は this を束縛しない」

bind() のサンプル

イベント処理の例

table td にイベント処理を付ける例。
JavaScript イベント処理 (1)


td.onclick = function(){  onclickTd(this); }; ではなく、下のようにした場合。

1) td.onclick = onclickTd;
   td.addEventListener("click", onclickTd);

  上の記述は関数のある場所(関数ポインタ)をセットしています。
  その場では実行しません。

  onclickTd(param) の引数 param はマウスイベントになります。
  呼び出し側でイベントの変数名を明示しなくても、暗黙で渡されます。

  onclickTd() 内の this は td になる点に注意。
  this は window オブジェクトではない点に注意。
  onclickTd() 内で他の関数を呼んで未定義(undefined)エラーが出る場合は、
 たいてい this 違いが原因です。bind() で this が何を指しているのか
 の明示が必要です。下の話に続く。

2) td.onclick = onclickTd.bind(this, td);
   td.addEventLisnter("click", onclickTd.bind(this, td));

  bind() を付けて引数を渡します。
  (補足)bind() は IE8 など古いブラウザで使えませんでした。

  td.onclick = function(){  onclickTd(this); }; とほぼ同じです。
  関数 onclickTd() の引数は td になります。(暗黙のうちにマウスイベントも
 引数の末尾に追加される)。

  bind() の最初のパラメータの this は関数onclickTd()内の this が何を
 指すかを指定します。
  このサンプルの場合は関数 onclickTd() 内の this は window になります。

  もし、アプリケーションのオブジェクト app があり、
  onclickTd.bind(app, td); とすれば、
  関数 onclickTd() 内の this は app、引数は td (とマウスイベント)になります。

・暗黙のうちにつくマウスイベントの引数は、暗黙に頼らず明示した方がいいかも?。
  暗黙に頼って省略すると誤解・錯覚の原因になりやすいです。

参考: bind() がなかった時代のコード (IE8以前)

古い JavaScript で下のような様式のコードが出てくることがあります。 bind() がなかった時代の独特な書き方です。 現在はこのように書く必要はありません。

var obj = new ( function(td){
	this.td = td;
	this.callback = function(){
		onclickTd(this.td);
	};
} )(td);  //最後の(td)はコンストラクタに渡す引数

関連

inserted by FC2 system