11

これについてSOに関する議論を読んだことは確かですが、見つかりません。簡単に言えば、ループの宣言内で for ループのインクリメントを宣言することに短所はありますか? これの違いは何ですか:

function foo() {
    for (var i=0; i<7; i++) {
        // code
    }
}

...この:

function foo() {
    var i;
    for (i=0; i<7; i++) {
        // code
    }
}

JSには関数スコープがあるので、どちらでもいいですよね?前者のアプローチが問題を引き起こすエッジケースはありますか?

それらが同一である場合、なぜ Crockford/JSLint はそれについてすべて「まさか」なのですか?

4

5 に答える 5

14

これらはまったく同じです。JavaScript のすべてのローカル変数には関数スコープがあります。これは、それらが宣言されている関数全体に対して有効であることを意味します。これは、ほとんどの中括弧言語が変数の有効期間を宣言されているブロックにスコープするため、最初は直観に反することがよくあります。

Javascript 開発者の一部は、2 番目の形式を非常に好みます。すべての変数には関数スコープがあるため、関数レベルで変数を宣言して、Javascript に慣れていない人でも寿命を明示する必要があるというのがその根拠です。これは単なるスタイルであり、決して難しいルールではありません

編集

ES6 letの導入により、ループ内で let を使用して、実際のブロックスコープ変数の詳細を確認できることに注意してください。

for(let i = 1; i <= 5; i++) {
   setTimeout(function(){
       console.log('Value of i : ' + i);
   },100);
}
于 2012-04-18T00:16:53.127 に答える
8

varループヘッダーでwith を宣言することの問題は、それが欺瞞的であることです。スコープがループに限定されている変数を宣言しているように見えますが、宣言のforを含め、実際には関数内のどこにでも存在します。

var i = 1;
function foo() {
   console.log(i);                     // 'undefined'
   for (var i=1; i<100; ++i) {
   }
}

console.log呼び出しは local の宣言の前に発生しますがi、同じ関数内にあるため、まだスコープ内にあります。iそのため、まだ値が割り当てられていないlocalが に渡されlogます。これは驚くべきことです。Javascript のスコープ ルールに慣れていない人にとっては、これは明らかなことではありません。

ECMAScript 2015から、変数を宣言するより良い方法があります: let. で宣言された変数はlet、関数全体ではなく、それらを含むブロックに対してローカルです。したがって、上記のコードのこのバージョンは1意図したとおりに出力されます。

let i=1; // could use var here; no practical difference at outermost scope
function foo() {
  console.log(i);               // 1
  for (let i=1; i<100; ++i) {
  }
}

したがって、最新の Javascript でのベスト プラクティスは、変数をletではなく で宣言することですvar。ただし、ECMAScript 2015 より前の実装に行き詰まっている場合は、最初に使用するまで待つのではなく、関数の先頭ですべての変数を宣言する方が少し混乱が少なくなります。

于 2012-04-18T00:19:19.700 に答える
1

違いはありませんが、変数が for ループの外で使用可能であることを明示的に示しているため、(Crockford によると) 2 番目の方法を好みます。

function() {
    for(var i=0; i<7; i++) {
        // code
    }

    // i is still in scope here and has value 7
}
于 2012-04-18T00:20:55.527 に答える
0

それらはどちらもまったく同じものです。

于 2012-04-18T00:15:07.393 に答える