Не делайте функции внутри цикла

Каков был бы правильный способ решить ошибку jslint в этом случае? Я добавляю функцию получения к объекту, который использует это. Я не знаю, как это сделать, не создавая функцию внутри цикла.

for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: function() { // TODO solve function in loop.
            return this.name_;
       }
   };
}

person Thijs Koerselman    schedule 25.04.2012    source источник
comment
Почему бы вообще не заглушить ошибку jslint? Вот как это сделать.   -  person lifebalance    schedule 22.10.2016
comment
Потому что ошибка есть по какой-то причине. Я не думаю, что очень приятно писать такой код, в котором множество одних и тех же функций создаются без какой-либо реальной причины.   -  person Thijs Koerselman    schedule 26.10.2016
comment
Иногда jslint не обязательно является окончательным руководством по правильному стилю кодирования...   -  person lifebalance    schedule 26.10.2016
comment
Верно (думаю, я не использовал jslint годами), но любой код, который создает много одних и тех же ресурсов без какой-либо реальной причины, в моей книге — плохой код. Единственная ситуация, в которой это было бы нормально, — это прирост производительности. В этом случае вы можете возразить, что это делает код более читабельным, но я считаю, что это очень незначительно. Как разработчик JavaScript, вы должны понимать, как работает this.   -  person Thijs Koerselman    schedule 27.10.2016


Ответы (1)


Переместите функцию за пределы цикла:

function dummy() {
    return this.name_;
}
// Or: var dummy = function() {return this.name;};
for (var i = 0; i<processorList.length; ++i) {
   result[i] = {
       processor_: timestampsToDateTime(processorList[i]),
       name_: processorList[i].processorName,
       getLabel: dummy
   };
}

... Или просто проигнорируйте сообщение, используя параметр loopfunc в верхней части окна. файл:

/*jshint loopfunc:true */
person Rob W    schedule 25.04.2012
comment
Ах, я не думал, что указатель this будет работать таким образом. Разве это не указывает на фиктивную функцию вместо объекта в результате [i]? Другими словами, правильно ли найдено name_? - person Thijs Koerselman; 25.04.2012
comment
@0x80 this указывает на контекст функции, который в данном случае равен results[i]. jsfiddle.net/W5vfw - person Rob W; 25.04.2012
comment
Замечательный! Спасибо, что объяснили это ясно. Это была одна из тех вещей, в которых я никогда не был уверен в Javascript. - person Thijs Koerselman; 25.04.2012
comment
@RobW: Могу я узнать, в чем разница, если просто вызвать именованную функцию в цикле? - person Amol M Kulkarni; 30.01.2013
comment
@AmolMKulkarni Когда функциональное выражение помещается в цикл, оно создается на каждой итерации. Перемещение выражения/объявления функции за пределы цикла имеет некоторые преимущества в производительности: jsperf.com/closure-vs-name-function-in-a-loop/2 - person Rob W; 30.01.2013
comment
Что происходит, когда вы хотите передать некоторые параметры в функцию? - person King Julien; 03.08.2013
comment
@Levani Тогда вам обычно требуется закрытие. - person Rob W; 03.08.2013
comment
Что, если в этом примере сама фиктивная функция создавала функцию? Должна ли эта функция быть объявлена ​​вне фиктивной функции? @РобВ - person ErikAGriffin; 08.07.2015
comment
@ErikAGriffin Это зависит. Это компромисс между производительностью и удобочитаемостью (и обычно вы должны отдавать предпочтение удобочитаемости). См., например. stackoverflow.com/questions/19779752/ для некоторых аргументов для и против вложенных функций. - person Rob W; 08.07.2015
comment
@RobW Код параметра jshint содержит ошибочный пробел (по крайней мере, в той версии, которую я использую). Это должно быть /*jshint loopfunc:true */ (без пробела перед буквой j), и оно должно быть вверху файла. - person tom; 29.04.2017