Function.prototype.bind( context ) を用いると "スコープ (this) の固定" が出来ます。
JavaScript で オブジェクト指向 な開発を行っていると、"スコープ (this) の固定" は大変便利です。
ここでは 関数の詳細 と 使用例 (jQuery) を記載します。
.bind(context [, arg1 [, arg2 [, ...]]])
概要
"this" および 引数 を固定して、新しい関数を生成します。
引数
- {object}context
- 関数の実行時に this として渡される値。
- {object...}arg1, arg2, ...
- 関数の実行時に引き渡される引数。
引数
- {function}
- "this" および 引数 を固定された関数。
イベント の アタッチ、デタッチ
サンプルコード
<!DOCTYPE html>
<html>
<head>
<title>Function.prototype.bind テスト</title>
</head>
<body>
<input type="button" id="attach" value="アタッチ" />
<input type="button" id="detach" value="デタッチ" />
<input type="button" id="button" value="実行" />
<script type="text/javascript" src="./jquery-1.10.2.js"></script>
<script type="text/javascript">
var garafu = garafu || {};
var instance;
/**
* @class サンプルクラス
* @constructor
*/
garafu.SampleClass = function (first, last) {
this.firstName = first || '雪ノ下';
this.lastName = last || '雪乃';
};
/**
* 挨拶を行います。
* @public
*/
garafu.SampleClass.prototype.sayHello = function () {
var message = '';
message += '私の名前は、';
message += this.firstName;
message += this.lastName;
message += 'です。';
window.alert(message);
};
// インスタンスの生成
instance = new garafu.SampleClass('由比ヶ浜', '結衣');
// ドキュメント生成後、イベントを貼り付ける
$(window).ready(function (event) {
// インスタンス を固定した 新しい関数 を生成
var callback = instance.sayHello.bind(instance);
$('#attach').on('click', function (event) {
// インスタンス を固定した 新しい関数 をアタッチ
// MEMO: [実行]ボタン 押下時、 "由比ヶ浜結衣" で表示される。
$('#button').on('click', callback);
});
$('#detach').on('click', function (event) {
// インスタンス を固定した 新しい関数 をデタッチ
$('#button').off('click', callback);
});
});
</script>
</body>
</html>
上記 サンプルコード では、いろいろと記述がありますが、.bind を利用しているのは ハイライト行 です。
.bind は新しい関数を生成するため、instance.sayHello と instance.sayHello.bind(instance) は異なります。
上記は正しく動作する サンプルコード で、以下では ダメな例 を記載します。
ダメな例1
$('#button').on('click', instance.sayHello);
コールバック関数 の実行時にエラーが発生します。
コールバック関数 の this が DOM要素 であるためです。
ダメな例2
$('#button').on('click', instance.sayHello.bind(instance));
こうしてしまうと、関数を指定して .off ができなくなってしまいます。
これは .bind を使うと新しい関数が生成され、元の関数とはインスタンスが異なるものになるためです。
今回、参考にしたサイトは以下の通りです。
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!