Можлива ітерація 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

Перевіряє наявність випадків нефільтрованих циклів входу в JavaScript. Використання цієї конструкції призводить до обробки успадкованих або несподіваних властивостей. Вам потрібно відфільтрувати власні властивості за допомогою методу hasOwnProperty (). Перевірка працює у файлах JavaScript, html або jsp.

Не могли б ви пояснити детальніше, що мається на увазі під цим твердженням?


2
jQuery не виконує hasOwnPropertyперевірок - мені цікаво, скільки попереджень це може спричинити ....
Alnitak

Відповіді:


151

IDE рекомендує додати тест:

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

всередині forпетлі.

Я особисто рекомендую цього не робити і, якщо це можливо, вимкнути попередження. У більшості кодів просто немає потреби, а ще менше в коді ES5, де ви можете безпечно додавати неперелічені властивості до об’єкта за допомогоюObject.defineProperty

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

jQuery не виконує цей тест - вони явно документують, що jQuery зламається, якщо Object.prototypeвін небезпечно змінений.


44
У IntelliJ 15, щоб вимкнути попередження, виконайте такі дії: Відкрийте Налаштування -> Редактор -> Стиль коду -> Інспекції. У вікні пошуку введіть "hasOwnProperty". Відобразиться "Нефільтрований для..в циклі". Зніміть цей прапорець. Натисніть кнопку OK, щоб прийняти зміни та закрити вікно.
Махтин

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]
});

-3

слід додати ще одну умову на початку цього циклу

if (awards.hasOwnProperty(i)) 

15
Я проголосував за цю відповідь, тому вважаю ввічливим, якщо скажу чому. Ця відповідь говорить про те, як уникнути попередження, але не пояснює, що означає попередження, як це уникає або що робить цей код.
WoodenKitty
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.