2009-08-26 1 views
3

これは私のコードの例である:私の入力にjQueryで適切なクロージャを作成するには?

var bar = function() { 

    this.baz = function() { 
    this.input = $('.input'); 
    this.input.bind("keydown keyup focus blur change", this.foo); 
    } 

    this.foo = function(event){ 
    console.log(this); 
    } 

} 

クリックすると、明らかに、私のコンソールでinputを与えます。代わりにbarthisとすることはできますか?

答えて

5

bindイベントが発生すると、イベントハンドラ関数がイベントをトリガしたDOM要素のコンテキストで呼び出されるため、thisキーワードはDOM要素を表します。あなたが外閉鎖への参照を格納する必要があり、「バー」を取得するための

var bar = function() { 
    var self = this; 

    this.baz = function() { 
    this.input = $('.input'); 
    this.input.bind("keydown keyup focus blur change", this.foo); 
    } 

    this.foo = function(event){ 
    console.log(this); // the input 
    console.log(self); // the bar scope 
    } 
}; 

注:バー機能がnewオペレータなしで呼び出された場合、thisは、ウィンドウオブジェクトとなり、bazfooはグローバル変数になりますので、注意してください!私はあなたのコードを簡素化することができると思いますが

var bar = { 
    baz: function() { 
    var input = $('.input'); 
    input.bind("keydown keyup focus blur change", this.foo); 
    }, 

    foo: function(event){ 
    console.log(this); // the input 
    console.log(bar); // reference to the bar object 
    } 
}; 
+0

「var bar =」の部分は本当に必要ないと付け加えます。クロージャをインラインで呼び出すには、最後のセミコロンの前に "()"を追加します。 – spoulson

+2

はい、ただし、クロージャが自動的に実行されると、 'this'がウィンドウオブジェクトになるため、' baz'と 'foo'がグローバルになります。 – CMS

+0

ありがとう、私はこの "外側の閉鎖"オプションと一緒に行くと思う。しかし、私はinput.bind()の中で、dunno、second bindのような、もっとエレガントなものを望んでいました。私はどこかでこのようなものを見たと感じています。他のオプションはありますか? – n1313

1

あなたのfooのバーを取得するには、次の操作を行います。ここでは

bar = function() { 

var me = this; 

this.baz = function() { 
    this.input = $('.input'); 
    this.input.bind("keydown keyup focus blur change", this.foo); 
} 

this.foo = function(event){ 
    // me, would be your bar object. 
    console.log(me); 
} 

} 
0

あなたがgo.thisは、「これを取得する方法のexmapleです"

<html> 
<head></head> 
<script type="text/javascript" src="jquery-1.3.2.min.js"></script> 

<script> 
var bar = function() { 

this.baz = function() { 
    this.input = $('.input'); 
    this.input.bind("keydown keyup focus blur change", this.foo); 
} 

this.foo = function(event){ 
    console.log(this); 
} 

} 

</script> 
<body> 
<input class="input"> 
<button onclick="new bar().baz()">Click</button> 
</body> 
</html> 

これは、bar.SOバーのインスタンスで関数bazが呼び出されたために発生します。「new bar() "コンテキストであり、ウィンドウオブジェクトではありません。

Firebugを使用している場合は、コンソールタブ内のクリックをクリックする前後で、入力テキストコントロール内に入力する際のログを追跡できます。

1

これは、JavaScriptでインスタンスメソッドをコールバックとして使用する場合の一般的な問題です。の一部とは違って

bound_method(this, this.foo) 

function bound_method(instance, method) { 
    return function() { 
    return method.apply(instance, arguments); 
    }; 
} 

が次にあなたがthis.fooの代わりにあなたのコールバックとしてこれを使用することができます:私は、正しいインスタンスにバインドされたメソッドを呼び出すためにクロージャを作成するには、この機能を使用します他の提案では、プロトタイプをコンストラクタで作成するのではなく、プロトタイプに配置することができます。この方法では、バーの新しいインスタンスごとにこれらの関数を再作成するのではなく、実装の共有コピーを1つだけ保持します。

var bar = function() {}; 
$.extend(bar, { 
    baz: function() { 
    this.input = $('.input'); 
    this.input.bind("keydown keyup focus blur change", 
        bound_method(this, this.foo)); 
    }, 

    foo: function(event) { 
    console.log(this); 
    } 
}); 
+0

あなたのbound_method()メソッドはbind()のように見えますが、そうですか? – n1313

+0

はい、それはPrototypeのFunction.bindや、新しいECMAScript標準にかなり似ています。Functionプロトタイプに追加することを考えましたが、組み込みオブジェクトプロトタイプの変更は避けています。 –

関連する問題