12

値として配列を持つオブジェクトがあります。

people = {
    'steve':['foo','bar'],
    'joe':['baz','boo']
}

キーごとに、対応する配列の値をループします。十分に単純:

for ( var person in people ) {
    person.forEach( function(item) {
      console.log(item)
    })
}

しかし、JSHintは不平を言います:

Don't make functions within a loop.

これは本当に私のコードの問題ですか?私は短いES5forループ構文がとても好きです。ES3スタイルを使用する必要がありますか、それとも他の方法でコードを変更する必要がありますか?

4

5 に答える 5

21

そこには2つの問題があります。1つはJSHintが警告している問題で、もう1つはより基本的な問題です。

JSHintが警告しているのは、理論的には、そのループが実行されるたびに、新しい関数が作成されるということです。これはより良いでしょう:

for ( var person in people ) {
    person.forEach(handlePerson);
}
function handlePerson(item) {
  console.log(item)
}

仕様では毎回新しい関数オブジェクトを作成する必要がありますが、それはエンジンが関数の基礎となる実装を再利用できないことを意味するわけではなく、エンジンが再利用できないことを意味するわけではないため、「理論上」と言います他のプロパティを割り当てていない場合、またはオブジェクトへの参照を保持していない場合は、同じ関数オブジェクト。私はV8の人たちにそれについて尋ねました(V8はChromeのJavaScriptエンジンです)、そして彼らはChromeが「...ほとんどの場合...」同じ時点で作成されたさまざまな関数オブジェクトの基礎となる関数実装を再利用すると言いましたソースコード、および他のほとんどのエンジンが同じことを行うことを「期待」すること。

したがって、この特定のケースでは、JSHintは少しやり過ぎかもしれません。ただし、特にループ内で作成している関数が、ループ中に内容が変更される変数を参照している場合は、これはしばしば有用な警告です。これは、人々が犯す典型的なクロージャーエラーです。

しかし、もっと基本的にpersonは、はString(のプロパティの名前ですpeople)であり、はありStringませんforEach。あなたが欲しかった:

for ( var person in people ) {
    people[person].forEach(handlePerson);
}
function handlePerson(item) {
  console.log(item)
}

...たとえば、people[person]そのキーの配列を取得します。

于 2012-05-04T15:35:53.943 に答える
9

他のコメント投稿者に加えて、自分が何をしているのかがわかっている場合は、JSHintオプションを使用してこの警告を無効にすることができますloopfunc

/*jshint loopfunc:true */

for ( var person in people ) {
  person.forEach( function(item) {
    console.log(item)
  })
}

JSHintオプションは、グローバル(NPMモジュールを使用している場合)、ファイルごと、または関数ごとに設定できます。

于 2012-05-04T17:38:29.033 に答える
1

ループ内での使用は許可されてforEachいますが、ループ内で関数を宣言することは許可されていません。

function looper (item) {
  console.log(item)
}

for ( var person in people ) {
    person.forEach(looper)
}

...それ以外の場合は、反復ごとに同じ関数を再作成します。

于 2012-05-04T15:35:41.870 に答える
0

これはforEachではなく、不平を言っている匿名関数です。

于 2012-05-04T15:36:01.870 に答える
0

foreachこれが問題になる理由は、これを行うたびに、ヒープ内の呼び出し内に無名関数への新しいオブジェクト参照が作成されるためです。関数をforループの外側の変数に割り当てた方がよいでしょう。そうすれば、メモリを不必要に消費することはありません。

于 2012-05-04T15:36:02.260 に答える