web-dev-qa-db-ja.com

JavaScriptループ変数スコープ

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'が印刷されます。

56
BlackBox

for- loop の「 初期化パラメーター 」については、MDNを参照してください。

式(割り当て式を含む)または変数宣言。通常、カウンター変数を初期化するために使用されます。この式は、オプションでvarキーワードを使用して新しい変数を宣言できます。 これらの変数はループに対してローカルではありません。つまり、forループと同じスコープ内にあります。この式の結果は破棄されます。

65

JavaScriptは、constletが導入されるまでブロックスコープを持っていませんでした。関数スコープであるvarだけです。 iの初期化は1つの関数内にあるため、その変数は同じ関数内のどこからでもアクセスできます。

[〜#〜] mdn [〜#〜] から:

重要:JavaScriptにはブロックスコープがありません。ブロックで導入された変数は、含まれる関数またはスクリプトにスコープされ、それらを設定する効果はブロック自体を超えて持続します。つまり、ブロックステートメントはスコープを導入しません。 「スタンドアロン」ブロックは有効な構文ですが、JavaScriptでスタンドアロンブロックを使用したくないのは、CやJavaでそのようなブロックを実行すると思われる場合、期待どおりに動作しないためです。

54
user2718994

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/

16
Matt Coarr

他の言語(例:Java、C++、C)とは異なり、JavaScriptはブロックスコープをサポートしていません。ループまたは関数で変数を宣言すると、そのスコープは関数本体内にあります

for(i=0; i<arr.length; i++) {
    var j=0;
    // ...
}

ここで、iはグローバル変数になり、jはループのある関数またはスクリプトに対してローカルになります。

10
Hitesh Kumar
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パターン

9
Matt Smith