JavaScript変数のスコープに関する簡単な質問。
alert()
関数がi
を返す代わりにundefined
の値を出力するのはなぜですか?
$(document).ready(function () {
for(var i = 0; i < 10; i += 1){
}
alert("What is 'i'? " + i);
});
私はJSを初めて使用しますが、他のほぼすべての言語では、forループのスコープ内の宣言にそのループの値が含まれますが、この場合はなぜですか?
つまりWhat is 'i'? 10'
が印刷されます。
JavaScriptは、const
とlet
が導入されるまでブロックスコープを持っていませんでした。関数スコープであるvar
だけです。 i
の初期化は1つの関数内にあるため、その変数は同じ関数内のどこからでもアクセスできます。
[〜#〜] mdn [〜#〜] から:
重要:JavaScriptにはブロックスコープがありません。ブロックで導入された変数は、含まれる関数またはスクリプトにスコープされ、それらを設定する効果はブロック自体を超えて持続します。つまり、ブロックステートメントはスコープを導入しません。 「スタンドアロン」ブロックは有効な構文ですが、JavaScriptでスタンドアロンブロックを使用したくないのは、CやJavaでそのようなブロックを実行すると思われる場合、期待どおりに動作しないためです。
JavaScriptの人々はこれを修正しようとしています!
EcmaScript6(別名EcmaScript 2015)は、昨年の夏に合格したjavascriptの最新バージョンであり、ブラウザーはその機能をサポートし始めたばかりです。
これらの機能の1つは、「let」式を使用したブロックスコープローカル変数です。現時点(2016年4月)では、Safariを除き、主要なブラウザーの現在のバージョンのほとんどがこれをサポートしています。これをサポートするモバイルブラウザはほとんどありません。
詳細については、こちらをお読みください(特に、「forループのスコープ変数」を参照): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
現在のブラウザのサポートをここで確認できます(Bindings-> let行を探します): https://kangax.github.io/compat-table/es6/
他の言語(例:Java、C++、C)とは異なり、JavaScriptはブロックスコープをサポートしていません。ループまたは関数で変数を宣言すると、そのスコープは関数本体内にあります
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
ここで、i
はグローバル変数になり、j
はループのある関数またはスクリプトに対してローカルになります。
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
上記がグローバル変数i
を作成すると述べるのは正しくありません。私はあなたが常にvar
を使用して変数を宣言する必要があると信じています(「変数」ではなく「プロパティ」を意図的に望んでいない限り-JSコーディングシナリオの99.99%ではほとんどありません)
var
に初期値を割り当てるときにi
を省略すると、ローカル変数またはグローバル変数さえ作成されず、グローバルオブジェクトのプロパティi
が作成されます(これは、/bebeは大部分がグローバル変数のように振る舞います-しかしそれらには微妙な違いがあります)。
より良いでしょう:
var i;
for(i=0; i<arr.length; i++) {
var j=0;
// ...
}
現在、ループはグローバル変数i
(または、このコードが関数に含まれている場合は関数ローカル変数i
)を使用しています
これについての詳細は varキーワードの機能 および Javascriptの変数とプロパティ
-注意してください、少し紛らわしいのは、2番目のループなどで変数を再宣言できることです
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
for(var i=0; i<9; i++){
document.write('i = ' + i + '<br>');
}
これは有効なようです(テスト時にエラーなし)。 JavaScriptで変数を再宣言できるようです-ただし、特別な場合を除いて、おそらくすべてのアイデアとは限りません-[Googleアナリティクスが変数の「安全な」再宣言を利用する方法について言及しているこの関連質問を参照してください( javascript変数の再宣言 )
この関連するSO質問: ループの内側または外側で変数を宣言する)で、JSの変数(およびi
などのループ変数)の再宣言に関するいくつかの議論があります。
イベントがあります 変数の単一宣言のJavaScriptパターン