私はjQuery.liveのような関数を構築しようとしています。 Helper
は、_liveEvent
と_addEventListener
のメソッドを持つクラスです。 Helper._addEventListener
はW3C addEventListener
のCrossBrowserバージョンです。DOMイベントコールバック内にクロージャが必要ですか?
Helper.prototype._liveEvent = function(type, evt, ofunc) {
var elHand = document;
type = type.toUpperCase();
this._addEventListener(elHand, evt, function(me) {
// Inside here I use the `type` variable.
// I don't know why but it works.
for (var el = me.srcElement; el.nodeName !== 'HTML';
el = el.parentNode)
{
if (el.nodeName === type || el.parentNode === null) {
break;
}
}
if (el && el.nodeName === type) {
ofunc.call(el, me);
}
});
};
私はさまざまな種類のHelper._liveEvent
機能を2回実行していますよ。そしてそれはうまく動作します。私は、type
変数が_liveEvent
コンテキスト内に設定されているので、_addEventListener
コールバックはその変数の最後のバージョンしか見ることができないと考えました。しかしそれは事実ではない、それは正常に動作しているようだ。
私の質問は以下のとおりです。
- _addEventListenerコールバックは、タイプの両方のバージョンを見ることができるのはなぜ?
- 私のコードはメモリをリークしているのですか?
UPDATE
この他の例では、私は、このより良い理解しました。しかし、私はまだそれを食べるのか分からない。
function foo(i) {
setTimeout(function() {
console.log(i);
}, 400);
}
// Prints 1, 2, 3
for (var i = 1; i < 4; i++) {
foo(i);
}
function bar() {
for (var i = 1; i < 4; i++) {
setTimeout(function() {
console.log(i);
}, 400);
}
}
// Prints 4, 4, 4
bar();
私は匿名関数を複数回作成したのではなく、複数の入力で_liveEventを複数回呼び出すため、変数に正しいスコープがあると思います。 – Eduardo
複数の '_liveEvent()'呼び出しを示唆しているのと同じことが、ここでは同じです(それぞれ "elHand"と "type"の値を持っています)。 '_addEventListener()'への2回の連続した呼び出しで追加されたリスナーは、2つの異なるFunctionオブジェクトです。 –
私の2番目の例を見てください。タイムアウトのあるもの。 fooとbarの両方が複数の無名関数を生成しますが、1つのみが動作します。スコープは、foo関数のパラメータによって保持されます。無名関数の作成ではありません。 – Eduardo