Возможная итерация JavaScript вышла из-за неожиданности

88

У меня такой код:

  for (i in awards) {
         if (awards[i] instanceof Array === false) {
               console.log(awards[i]);
                httpFactory.patch(awards[i], {"read": true}, false);
             }
       }

Моя IDE показывает эту ошибку, связанную с приведенным выше кодом:

Возможная итерация по неожиданным (настраиваемым / унаследованным) членам, возможно, отсутствует проверка hasOwnProperty

Проверяет наличие нефильтрованных циклов for-in в JavaScript. Использование этой конструкции приводит к обработке унаследованных или неожиданных свойств. Вам необходимо отфильтровать собственные свойства с помощью метода hasOwnProperty (). Проверка работает в файлах JavaScript, html или jsp.

Не могли бы вы подробнее объяснить, что подразумевается под этим утверждением?

Прометей
источник
2
jQuery не выполняет hasOwnPropertyпроверки - мне интересно, сколько предупреждений будет выдано ....
Альнитак

Ответы:

151

IDE рекомендует добавить тест:

if (awards.hasOwnProperty(i)) {
    ...
}

внутри forпетли.

Я лично рекомендую не делать этого и, если возможно, отключить предупреждение. Просто нет необходимости в большей части кода, и еще меньше необходимости в коде ES5, где вы можете безопасно добавлять неперечислимые свойства к объекту, используяObject.defineProperty

hasOwnPropertyПроверка необходима только если вы небезопасное добавлены новые (перечисляемые) свойства Object.prototype, поэтому самое простое исправление не делает этого .

jQuery не выполняет этот тест - они явно документируют, что jQuery сломается, если Object.prototypeбудет небезопасно изменен.

Альнитак
источник
44
В IntelliJ 15, чтобы отключить предупреждение, выполните следующие действия: Откройте «Настройки» -> «Редактор» -> «Стиль кода» -> «Проверки». В поле поиска введите hasOwnProperty. Будет отображено «Нефильтровано для..в цикле». Снимите этот флажок. Нажмите кнопку ОК, чтобы принять изменения и закрыть окно.
Machtyn
2
В IntelliJ: CTRL ALT S (если вы не используете Ubuntu, у которого есть собственный ярлык CTRL ALT S) просто найдите «hasOwnProperty», и вы сразу перейдете к проблеме, снимите флажок и готово!
Оливье Понс
2
В WebStorm перейдите в меню «Файл ... Настройки», затем «Редактор» -> «Инспекции» -> «JavaScript и TypeScript» -> «Общие» и снимите флажок «Без фильтрации для..в цикле».
mightypile
@Machtyn Нет необходимости заходить в настройки, чтобы отключить это предупреждение. В Linux / Windows нажмите Alt + Enter, наведя курсор на предупреждение, выберите первый параметр во всплывающем контекстном меню и отключите параметр в подменю рядом с первым параметром.
peterchaula
22

Каждый объект в javascript имеет прототип, который имеет свои собственные свойства (собственные / унаследованные методы / свойства) и свойства, которые напрямую привязаны к самому объекту.

Когда вы перебираете объект, он будет перебирать свойства самого объекта и свойства прототипа объекта.

Итак, чтобы избежать итерации по прототипу, рекомендуется использовать метод hasOwnProperty, который возвращает true только тогда, когда объект имеет указанное свойство напрямую. т.е. не внутри прототипа

пример

for (var k in object) {
  if (object.hasOwnProperty(k)) {
     // do your computation here.
  }
}

Более подробную информацию можно найти здесь

Сельварадж М.А.
источник
15

Вы также можете преобразовать свой цикл в:

const keys = Object.keys(object);
for (const key of keys){
   // do something with object[key];
}
Флавьен Волкен
источник
3

Также вы можете избавиться от предупреждения, написав цикл forEach для более удобочитаемого и функционального подхода:

Object.keys(object).forEach(key => {
    // Do something with object[key]
});
jnd0
источник
-3

вы должны добавить еще одно условие в начале этого цикла

if (awards.hasOwnProperty(i)) 
бмазурек
источник
15
Я отклонил этот ответ, поэтому считаю вежливым, если я скажу, почему. В этом ответе говорится, как избежать предупреждения, но не объясняется, что означает предупреждение, как его избежать или что делает этот код.
WoodenKitty