Function.prototype.bind を用いた イベント の アタッチ、デタッチ

0 件のコメント

Function.prototype.bind( context ) を用いると "スコープ (this) の固定" が出来ます。 JavaScript で オブジェクト指向 な開発を行っていると、"スコープ (this) の固定" は大変便利です。

ここでは 関数の詳細 と 使用例 (jQuery) を記載します。

.bind(context [, arg1 [, arg2 [, ...]]])

概要

"this" および 引数 を固定して、新しい関数を生成します。

引数

{object}context
関数の実行時に this として渡される値。
{object...}arg1, arg2, ...
関数の実行時に引き渡される引数。

引数

{function} 
"this" および 引数 を固定された関数。

イベント の アタッチ、デタッチ

サンプルコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!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.sayHelloinstance.sayHello.bind(instance) は異なります。 上記は正しく動作する サンプルコード で、以下では ダメな例 を記載します。

ダメな例1

50
$('#button').on('click', instance.sayHello);

コールバック関数 の実行時にエラーが発生します。 コールバック関数 の this が DOM要素 であるためです。

ダメな例2

50
$('#button').on('click', instance.sayHello.bind(instance));

こうしてしまうと、関数を指定して .off ができなくなってしまいます。 これは .bind を使うと新しい関数が生成され、元の関数とはインスタンスが異なるものになるためです。

今回、参考にしたサイトは以下の通りです。

最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!