Я использовал JSLint для моего файла JavaScript. Выкинуло ошибку:
for( ind in evtListeners ) {
Проблема в строке 41, символ 9. Тело for in должно быть заключено в оператор if, чтобы отфильтровать нежелательные свойства из прототипа.
Что это значит?
javascript
jslint
jrharshath
источник
источник
if (evtListeners.hasOwnProperty(ind))
чтобы ограничить обработку только собственными (не унаследованными) свойствами. Тем не менее, в некоторых случаях вы действительно хотите перебрать все свойства, включая унаследованные. В этом случае JSLint заставляет вас обернуть тело цикла в оператор if, чтобы решить, какие свойства вы действительно хотите. Это сработает и сделает JSlint счастливым:if (evtListeners[ind] !== undefined)
Ответы:
Прежде всего, никогда не используйте
for in
цикл для перечисления по массиву. Никогда. Используйте старый добрыйfor(var i = 0; i<arr.length; i++)
.Причина этого заключается в следующем: каждый объект в JavaScript имеет специальное поле с именем
prototype
. Все, что вы добавите в это поле, будет доступно для каждого объекта этого типа. Предположим, вы хотите, чтобы у всех массивов была новая классная функция,filter_0
которая будет фильтровать нули.Это стандартный способ расширения объектов и добавления новых методов. Многие библиотеки делают это. Однако давайте посмотрим, как
for in
работает сейчас:Ты видишь? Он вдруг думает, что filter_0 - это еще один индекс массива. Конечно, это на самом деле не числовой индекс, а
for in
перечисление через поля объекта, а не только числовые индексы. Итак, мы сейчас перечисляем все числовые индексы иfilter_0
. Ноfilter_0
это не поле какого-либо конкретного объекта массива, каждый объект массива теперь имеет это свойство.К счастью, у всех объектов есть
hasOwnProperty
метод, который проверяет, действительно ли это поле принадлежит самому объекту или оно просто унаследовано от цепочки прототипов и, следовательно, принадлежит всем объектам этого типа.Обратите внимание, что, хотя этот код работает, как и ожидалось, для массивов, вы никогда не должны использовать никогда
for in
иfor each in
для массивов. Помните, чтоfor in
перечисляет поля объекта, а не индексы или значения массива.источник
for in
для итерации массивов, поскольку язык не гарантирует порядок, в которомfor in
будет перечисляться массив. Это может быть не в порядке номеров. Кроме того, если вы используете стилевую конструкцию `for (i = 0; i <array.length; i ++), вы можете быть уверены, что выполняете только числовые индексы в порядке, а алфавитно-цифровые свойства отсутствуют.for-in
циклов (что, кстати, здорово), мы должны научить их, как они работают (правильно сделано в этом ответе), и познакомить их сObject.defineProperty()
тем, чтобы они могли безопасно расширять свои прототипы, ничего не нарушая. Кстати, расширение прототипов нативных объектов не должно обойтись безObject.defineProperty
.Дуглас Крокфорд, автор jslint, писал (и говорил) об этой проблеме много раз. На этой странице его сайта есть раздел, который охватывает это:
У Крокфорда также есть видеосериал о театре YUI, где он рассказывает об этом. Крокфордские серии видео / разговоров о javascript - это то, что нужно посмотреть, если вы хоть немного серьезно относитесь к javascript.
источник
Плохо: (jsHint выдаст ошибку)
Хорошо:
источник
Вава ответ на вопрос. Если вы используете jQuery, то
$.each()
функция позаботится об этом, поэтому безопаснее в использовании.источник
$.each
(или underscore.js_.each
), если вы можете избежать необработанногоfor
цикла. У jsperf есть несколько сравнительных тестов , которые стоит запустить.@all - все в JavaScript является объектом (), поэтому такие выражения, как «использовать это только для объектов», немного вводят в заблуждение. Кроме того, JavaScript не является строго типизированным, поэтому 1 == «1» - это правда (хотя 1 === «1» - нет, Крокфорд в этом преуспел). Когда дело доходит до прогроматической концепции массивов в JS, в определении важна типизация.
@ Брентон - Не нужно быть диктатором терминологии; «ассоциативный массив», «словарь», «хэш», «объект», все эти концепции программирования применимы к одной структуре в JS. Это пары имя (ключ, индекс), где значением может быть любой другой объект (строки также являются объектами)
Итак, так
new Array()
же, как[]
new Object()
примерно похож на{}
Создает структуру, которая является массивом с ограничением, что все индексы (или ключи) должны быть целыми числами. Это также позволяет автоматически назначать новые индексы с помощью .push ()
Это действительно лучше всего решать с помощью
for(initialization;condition;update){
Но что насчет:
Попробуй это:
Возможно, не лучшее использование массива, а просто иллюстрация того, что вещи не всегда понятны.
Если вы знаете свои ключи и определенно, если они не являются целыми числами, ваш единственный вариант структуры массива - это объект.
источник
Конечно, это немного экстрим, чтобы сказать,
?
Стоит выделить раздел в выдержке Дугласа Крокфорда
Если вам требуется ассоциативный массив (он же hashtable / dictionary), в котором ключи именуются, а не численно индексируются, вам придется реализовать это как объект, например
var myAssocArray = {key1: "value1", key2: "value2"...};
.В этом случае
myAssocArray.length
придет ноль (потому что у этого объекта нет свойства 'length'), и выi < myAssocArray.length
не получите слишком далеко. В дополнение к обеспечению большего удобства, я ожидаю, что ассоциативные массивы обеспечат преимущества производительности во многих ситуациях, поскольку ключи массива могут быть полезными свойствами (т. Е. Свойством или именем идентификатора члена массива), то есть вам не нужно перебирать длинный массив повторно вычисляет операторы if, чтобы найти запись массива, которую вы ищете.В любом случае, спасибо также за объяснение сообщений об ошибках JSLint, теперь я буду использовать проверку 'isOwnProperty' при работе с моими бесчисленными ассоциативными массивами!
источник
length
свойства, но вы можете сделать это по-другому:var myArr = []; myArr['key1'] = 'hello'; myArr['key2'] = 'world';
var myArr = []
, это должно бытьvar myArr = {}
в PHP, это то же самое, но не в JS.Это означает, что вы должны фильтровать свойства evtListeners с помощью метода hasOwnProperty .
источник
Просто чтобы добавить к теме для in / for / $. Каждый, я добавил тестовый пример jsperf для использования $ .each против for in: http://jsperf.com/each-vs-for-in/2.
Разные браузеры / версии обрабатывают его по-разному, но кажется, что $ .each и сразу - самые дешевые варианты с точки зрения производительности.
Если вы используете for для перебора ассоциативного массива / объекта, зная, что вам нужно, и игнорируя все остальное, используйте $ .each, если вы используете jQuery, или просто for in (и затем разрыв; как только вы достиг того, что вы знаете, должен быть последним элементом)
Если вы перебираете массив для выполнения чего-либо с каждой парой ключей в нем, следует использовать метод hasOwnProperty, если вы НЕ используете jQuery, и использовать $ .each, если вы действительно используете jQuery.
Всегда используйте,
for(i=0;i<o.length;i++)
если вам не нужен ассоциативный массив, хотя ... LOL Chrome выполнил это на 97% быстрее, чем для In или$.each
источник