JavaScript可能发生意外迭代


83

我有以下代码:

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

我的IDE显示与上述代码有关的错误:

可能对意外(自定义/继承)成员进行迭代,可能缺少hasOwnProperty检查

检查JavaScript中未过滤的for-in循环的任何实例。使用此构造会导致处理继承或意外的属性。您需要使用hasOwnProperty()方法过滤自己的属性。验证适用于JavaScript,html或jsp文件。

您能否更详细地解释此声明的含义?


2
jQuery的不执行hasOwnProperty检查-我不知道这会产生多少的警告....
参宿

Answers:


145

IDE建议您添加一个测试:

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

for循环内。

我个人建议不要这样做,并尽可能禁用警告。基本上,大多数代码都不需要,甚至在ES5代码中也不再需要,在这些代码中,您可以使用Object.defineProperty

hasOwnProperty检查只需要如果你有不安全添加新的(枚举)属性Object.prototype,因此最简单的解决方法是不这样做

jQuery不会执行此测试-他们明确记录了如果Object.prototype不安全地修改jQuery将会破坏。


40
在IntelliJ 15中,要禁用警告,请执行以下操作:打开“首选项”->“编辑器”->“代码样式”->“检查”。在搜索框中,输入“ hasOwnProperty”。它将显示“ Unfiltered for..in loop”。取消选中该框。单击确定按钮接受更改并关闭窗口。
Machtyn

2
在IntelliJ中:CTRL ALT S(除非您使用的是具有自己的CTRL ALT S快捷方式的Ubuntu),只需搜索“ hasOwnProperty”,您将直接解决问题,取消选中它就完成了!
奥利维尔·庞斯

1
在WebStorm中,转到“文件...设置”,然后转到“编辑器”->“检查”->“ JavaScript和TypeScript”->“常规”,然后取消选中“未过滤的..in循环”。
mightypile

21

javascript中的每个对象都有一个原型,该原型具有自己的属性(本机/继承的方法/属性)以及直接附加到对象本身的属性。

迭代对象时,它将迭代对象本身的属性和对象原型的属性。

因此,为了避免迭代原型,建议使用hasOwnProperty方法,该方法仅在对象具有直接提到的属性时才返回true。即不在原型内

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

更多细节可以在这里找到


13

您还可以将循环重构为:

const keys = Object.keys(object);
for (const key of keys){
   // do something with object[key];
}

3

同样,您也可以摆脱写警告for aeach循环的警告,从而获得更具可读性和实用性的方法:

Object.keys(object).forEach(key => {
    // Do something with object[key]
});

-2

您应该在此循环的开头再添加一个条件

if (awards.hasOwnProperty(i)) 

13
我否决了这个答案,所以如果我说为什么,那是礼貌的。此答案说明了如何避免警告,但没有说明警告的含义,避免的方式或此代码的作用。
WoodenKitty
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.