2014-01-14 6 views
12

JavaScriptには機能スコープしかありません。したがって、forループで宣言された変数は、関数全体で表示されます。例えば複数のforループで宣言された変数を処理するための最も慣用的な方法は何ですか?

function foo() { 
    for(var i = 0; i < n; i++) { 
     // Do something 
    } 
    // i is still in scope here 
} 

我々はforループの複数を持っている場合は、これは我々がループのために、これらの他の変数をどのように処理するかの質問を開きます。

別の変数を使用していますか?

for(var i = 0; i < n; i++) { } 
for(var j = 0; j < n; j++) { } 

同じ変数を使用していますが、宣言する代わりに値を割り当てるだけですか?

for(var i = 0; i < n; i++) { } 
for(i = 0; i < n; i++) { } 

またはループのi外を宣言?

var i; 
for(i = 0; i < n; i++) { } 
for(i = 0; i < n; i++) { } 

またはiを再宣言してください。

for(var i = 0; i < n; i++) { } 
for(var i = 0; i < n; i++) { } 

これらのすべての作業(または少なくとも私のブラウザの最新バージョンを使用しています)。しかし、JSHintは最後のアプローチを好まない。

最も慣れ親しんでいるか、そうでなければ好ましいアプローチがありますか?

+1

最後の2つのいずれかを使用します。私はJSHintの苦情にもかかわらず、最後のものが好きです。私がそれを沈黙させなければならなかったら、私は前のものを使います。 – Barmar

+4

記録のために、JavaScriptはブロックスコープを獲得しています。だから、今後も['for(let i ... ...)'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)、これは 'i'をループのローカルとして宣言します。 –

+1

私は両方のループの外側で一度 'i'を宣言することを好みます(関数の先頭に必ずしもある必要はありません - 一行にすべてを置く/カンマで区切ってください)。しかし、あまりにも多くの機能が必要なのでしょうか? – Ryan

答えて

3

本当にあなたが誰をコーディングしているかによって異なります。あなたが会社をコーディングしている場合や、図書館に寄稿している場合は、もちろんスタイルガイドに従ってください。私はライブラリの中で使われているすべてのものを見てきました。 Douglas Crockfordスタイルが好きな人は、2番目と最後にすべての変数を関数スコープの先頭に置く(またはjslintがあなたに叫ぶでしょう)。jQuery style guideから例に取る

これは貧しいスタイルですがこれは

var i = 0; 

if (condition) { 
    doSomething(); 
} 

while (!condition) { 
    iterating++; 
} 

for (; i < 100; i++) { 
    object[ array[ i ] ] = someFn(i); 
} 

良いスタイルと考えられている:これはスタイルですので、とにかく

// Bad 
if(condition) doSomething(); 
while(!condition) iterating++; 
for(var i=0;i<100;i++) object[array[i]] = someFn(i); 

私はいくつかのライブラリがそれぞれのlおっと:

あなたはそれを解放する前に、あなたのコードが最小化されようとしている場合minifiersは、処理中にほとんど同じエンド表現にそれをマングルうとして、それは問題ではありません。

+0

forループの初期化セクションではなく、宣言時に 'i'を初期化することをお勧めしますか? :( –

3

異なる変数を使用しても問題はありません。

コードを再利用して再割り当てすると、コードが読みにくくなり、後で宣言を削除すると、iを関数スコープ外のものに割り当てる危険があります。

私はループ外に私を宣言しても問題はありません。

あなたのlintツール、IDEなどが不平を言うと再宣告が問題になります。

私は第1または第3の選択肢について主張します。最初のオプションを使用して変数の数が問題になる場合は、リファクタリングを必要とする可能性があります。

1

関数内で宣言された変数は、関数の先頭で宣言されたものとして解釈されます。 Doug Crockfordは、すべての関数をすべての関数の最初の行に宣言する必要があると主張しています。

doSomething = function() { 
    var i, ... other variables ...; 
    ... 
    for (i = 0; i < x; i += 1) { 
     ... 
    } 
    ... 
    for (i = 0; i < x; i += 1) { 
     ... 
    } 
} 

このように、コードはjavascriptエンジンによって解析されるのと同じ方法で読み込まれます。

3

別の方法で質問に答える別テイク。

ので、複数のループを持つ関数は、私は不審になり:それはあまりやっていることと、とにかく分解されなければならない

  1. 、および
  2. より多くの機能的にそれを書いて、インデックスを排除する方が良いかもしれ完全に(それはいくつかのeachで利用可能です - とにかく/ map -y機能)
3

別のアプローチは、イテレータの機能を使用することです。例えば、最近のブラウザでArrayforEach方法があります:あなたは古いブラウザ(またはカスタムコレクション)を使用している場合は、あなたが作ることができ

var items = ["one", "two", "three"]; 
var things = ["hello", "goodbye"]; 

items.forEach(function (item, index) { 
    // Do stuff 
}); 

things.forEach(function (item, index) { 
    // Do stuff 
}); 

をこのような独自のイテレータ:

Array.prototype.forEach = function(callback) {  
    for(var i = 0; i < this.length; i++) { 
     callback.apply(this, [this[i], i, this]); 
    } 
}; 

詳細については、Array.prototype.forEach()

関連する問題