それは、実際には、その変数がどこに存在する必要があるかによって異なります。JS は、変数を現在のスコープ (宣言されているスコープ) の先頭に持ち上げるか、var が宣言されていない場合は (悪) グローバルを作成します。
ループ内で var を宣言しても問題ありません。
for (var i=0;i<10;i++)
{
var j = 1*2;
}
に翻訳されます:
var i, j;
for (i=0;i<10;i++)
{
j = 1*2;
}
ただし、いくつかの「経験則」があります。
- グローバル変数を使用している場合は、おそらく間違いを犯しています
- ループ内で変数を宣言している場合、おそらくその変数は必要ありません
- 変数を宣言していない場合は、スクリプトで次のことを試してください。
(function()
{
'use strict';
//your code here
}());
そして、暗黙のグローバルフリーになるまでデバッグしてください。
あなたの例でshow_id
は、グローバルスコープ($(document).ready(callback
とにかくスコープ)で宣言するか、click
ハンドラー内で宣言するかの選択を「提供」しています。コールバックで変数を宣言することを妨げるものは何もありませeach
ん。この場合、大きな違いはありませんが、それは別の問題です。
JS では、すべての関数に独自のスコープがあり、必要なスコープで変数を宣言します。
そうは言っても、パフォーマンスタグに気づいただけで、コードは効率の点で最悪です。行をループして、イベント ハンドラーを全体にバインドする代わりに、イベントをデリゲートします。
$('#my_table').on('click','tr',function(e)
{
var show_id = e.target.attr('data-show-id');
});
このコードでshow_id
は、クリック ハンドラーが返された後に GCshow_id
されます。たとえば、次の行がクリックされたときを確認するために保持する必要がある場合です。
$('#my_table').on('click','tr',(function (show_id)
{
return function(e)
{
console.log('show_id was: ' + show_id);
show_id = e.target.attr('data-show-id');
console.log('and is now: ' + show_id);
};
}()));
console.log(show_id);//undefined
変数はスコープ内に保持されます ( でラップされた関数return function
は、show_id
宣言されたとおりのスコープですが、その戻り値はその変数を参照するため、GC されません。その返された関数の外側では、より高いスコープにいるため、変数にまったくアクセスできません。できることは、その値を公開することです。
var someVar = {};
$('#my_table').on('click','tr',(function (show_id)
{
return function(e)
{
show_id = e.target.attr('data-show-id');
someVar.myTableClicks = show_id;
console.log(someVar.myTableClicks);//value of show_id
};
}()));
console.log(someVar.myTableClicks);//undefined
//after a couple of clicks
console.log(someVar.myTableClicks);//some value
show_id
これで、アクセスできる場所ならどこでもの値にアクセスできますsomeVar
。
個人的には、いくつかの変数を使用できるようにする必要があるグループ コードを保持することを好みます。
var access = (function(timer)
{
var speed = 100,
begin = function(callback, interval)
{
speed = +(interval) || speed;
timer = setInterval(callback, speed);
},
stop = function()
{
clearInterval(timer);
};
return {start: start, stop: stop};
}());
この例では、start
とstop
関数の両方が var にアクセスする必要がありますが、timer
外部からのコードが の値を台無しにしたくないtimer
ので、これらの関数のみを公開しています。私の知る限り、コールバック引数関数にはtimer
またはspeed
参照を含めることができますが、コールバック関数は定義により別のスコープで宣言されるため、シールドしようとしているspeed
および変数を参照しません。したがって、アクセスできませんこのスコープ。それでも、絶対に確実にしたい場合は、いつでもこれを行うことができます:timer
var access = (function(timer)
{
var speed = 100,
begin = function(callback, interval)
{
speed = +(interval) || speed;
timer = (function(timer, speed)
{//masks timer & speed from the higher scope
return setInterval(callback, speed);
}('abc', 'def'));//assign dummy values
timer = setInterval(callback, speed);
},
stop = function()
{
clearInterval(timer);
};
return {start: start, stop: stop};
}());