Вопрос по javascript – JSHint не позволит мне использовать forEach в цикле for

11

У меня есть объект с массивами в качестве значений.

<code>people = {
    'steve':['foo','bar'],
    'joe':['baz','boo']
}
</code>

Для каждого ключа я хотел бы перебрать значения в соответствующем массиве. Достаточно просто:

<code>for ( var person in people ) {
    person.forEach( function(item) {
      console.log(item)
    })
}
</code>

Но JSHint жалуется:

<code>Don't make functions within a loop.
</code>

Это действительно проблема с моим кодом? Мне очень нравится короткий ES5 для синтаксиса цикла. Нужно ли использовать стиль ES3 или изменить код другим способом?

Ваш Ответ

4   ответа
19

та, о которой вас предупреждает JSHint, и более фундаментальная.

То, о чем тебя предупреждает JSHint, это то, что в теории,каждый ра этот цикл запускается, создается новая функция. Это было бы лучше:

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

Я говорю "в теории", потому что хотя спецификация требует, чтобы новая функция Объект создаваться каждый раз, это не значит, что движки не могут повторно использовать базовыйреализаци функции, и это не означает, что движки не могут повторно использовать один и тот же объект функции, если вы не присвоили ему другие свойства или не оставили ссылку на него. Я спросили об этом ребята из V8 (V8 - это движок JavaScript в Chrome), и они сказали, что Chrome будет "... в большинстве случаев ..." повторно использовать базовую реализацию функций для различных объектов функций, созданных в одной точке исходного кода, и что они будет "ожидать", что большинство других двигателей будут делать то же самое.

Так что JSHint может быть немного непосильным в данном конкретном случае. Но это часто полезное предупреждение, особенно если функции, которые вы создаете внутри цикла, ссылаются на переменные, содержимое которых изменяется во время цикла, что является классической ошибкой закрытия, которую делают люди.

Но более фундаментально,person этоString (это название свойства вpeople), а такжеString не имеетforEach. Вы хотели

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

... например,people[person] чтобы получить массив для этого ключа.

Думаю, он имел в видуpeople[person].forEach(...). В любом случае, это предупреждение кажется довольно глупым с современными движками JS - они, скорее всего, не будут создавать новую функцию для каждой итерации. ThiefMaster♦
По крайней мере, V8 этого не делает: / Stackoverflow.com вопросы / 10160275 / ... ThiefMaster♦
@ Ракета: Черт возьми, это прямо в вопросе.вздо Благодарность T.J. Crowder
При использовании анонимных функций в цикле все еще наблюдается некоторое снижение производительности. Jsperf.com / Анон-против-имени-в-петле cliffs of insanity
@ user1370958: Могу поспорить, что это связано с встраиванием и / или созданием обёртки объекта. Очень полезные данные. Кстати, будьте осторожны, это не разница между именованными и анонимными функциями, это разница между созданием функций в цикле или нет. Функции в цикле могут иметь имена (используя выражения именованных функций), а функция, не созданная в цикле, может быть анонимной (присваиваться переменной). T.J. Crowder
8

если вы знаете, что делаете, вы можете отключить это предупреждение с помощью опции JSHintloopfunc:

/*jshint loopfunc:true */

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

Вы можете установить параметры JSHint глобально (если вы используете модуль NPM), для файла или для функции.

Читая это в 2016 году: я очень много сделалн знаю, что я делал. PS. Привет Антон! mikemaccana
1

Вы можете использоватьforEach внутри цикла, но вы не можете объявить функцию внутри цикла.

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

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

... в противном случае вы воссоздаете одну и ту же функцию для каждой итерации.

0

что он создает новую ссылку на объект на анонимную функцию внутриforeach вызывать кучу каждый раз, когда вы делаете это. Было бы лучше, если бы вы присвоили функцию переменной вне цикла for, чтобы вы не тратили память напрасн

Похожие вопросы