複雑なjQuery/javascriptを作成している場合、以前に定義された変数をthis
再定義せずに、どのように使用を管理しますか?this
変数に名前を付けるための経験則または個人的な好みはありますthis
か(ネストが深くなるにつれて)?
より高いスコープの変数をネストされた関数/コールバックで使用できるようにしたい場合もありますが、クリーンなスレート/スコープが必要な場合もあります。変数の衝突を心配せずに関数/コールバックを呼び出す良い方法はありますか?もしそうなら、あなたはどのようなテクニックを使っていますか?
いくつかの非常にばかげたテストコード:
$(document).ready(function() {
console.warn('start');
var $this = $(this),
$dog = $('#dog'),
billy = function() {
console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);
var $this = $(this);
console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);
};
// (#1)
billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
// BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(Document /demos/this/) | DOG: jQuery(p#dog)
// (#2)
billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
// BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
$('#foo').slideUp(function() {
// (#3)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this); // (#10)
// (#4)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
});
$('#clickme').click(function() {
// (#5)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this);
// (#6)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(button#clickme) | DOG: jQuery(p#dog)
$('#what').animate({
opacity : 0.25,
left : '+=50',
height : 'toggle'
}, 500, function() {
// (#7)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this);
// (#8)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(div#what) | DOG: jQuery(p#dog)
});
});
// (#9)
billy(); // THIS: undefined | DOG: jQuery(p#dog)
// THIS: jQuery(div#foo) | DOG: jQuery(p#dog)
console.warn('finish');
});
注:ご覧のとおり、簡単に参照できるように、コメントに番号(#XX)を付けています。
観察1:
マーカー(#1)
BILLY! THIS: undefined | DOG: jQuery(p#dog)
修辞的な質問:なぜ$this
未定義なのに$dog
アクセスできるのですか?
回答:var
その範囲内で再定義されているため$this
; $this
そのスコープ内で定義される前にログに記録しようとしているだけです。
コメントアウトするvar $this = $(this);
と、マーカー(#1)は次のように戻ります。
BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
同じロジックがマーカー(#2)、(#3)、(#4)、(#5)、(#6)、(#7)、および(#8)にも適用されます。
この観察に基づいて(そして私がここで間違っている場合は私を訂正してください)私はvar $this = $(this);
関数の一番下に置くことができると仮定しています、そして現在のスコープは私が現在のスコープを使いたいと知っているでしょう$this
(そうではありませんがまだ定義されています)、親のものではありません(定義$this
されている場合でも)。
競合を回避するための可能な解決策$this
:
他のクロージャ/関数/コールバックの外部/内部をキャッシュして$(this)
衝突を回避したい場合は、次のような異なる変数ラベルを使用する必要があります(たとえば)。
var $$ = $(this);
var $this2 = $(this);
var $t = $(this);
var $that = $(this);
質問:
$this
上記の解決策は、衝突を回避する方法ですか?そうでない場合、あなたが好むテクニックは何ですか?
観察2:
マーカー(#9)
THIS: undefined | DOG: jQuery(p#dog)
...$this
上記の理由で定義されていませんが、:
THIS: jQuery(div#foo) | DOG: jQuery(p#dog)
...$this
今$('#foo')
です!
質問:
正確になぜこれが起こったのですか?
マーカー(#10)$this
で再定義されたからですか?
(うーん、Googleの「javascriptのガベージコレクション」が必要な気がします。)
繰り返しますが、複雑なjquery / javascriptを作成する場合、このタイプの変数の衝突を回避するための最良の方法は何ですか?
これらが恐ろしい質問ではないことを願っています。お手数をおかけしますが、よろしくお願いいたします。:)