这个for-in循环检测代码段会产生有害的误报吗?

问题描述:

我们都知道 for-in-loops 数组上的a>是绝对邪恶.仍然经常使用它们,并且导致的错误很难找到,特别是在发生与浏览器有关的情况时,例如由于indexOf -shims等.

We all know that for-in-loops on arrays are absolutely evil. Still, they are often used and the caused errors are complicated to trace down, especially when happening browser-dependent for example because of indexOf-shims or such.

因此,我编写了这个简单的代码段,为Array.prototype上的"error"属性添加了一个可枚举的吸气剂(不适用于生产代码):

So, I have coded this simple snippet which adds an enumerable getter for a "error" property on Array.prototype (not for use in production code):

Object.defineProperty(Array.prototype, "error", {
    enumerable: true,
    get: function() {
        if (this === Array.prototype) // that looks OK
            return undefined;
        if (window.confirm("Somebody who coded the site you're viewing runs through an Array with a for-in-loop.\nShame on him!\n\nDo you want to raise an Error to trace the origin?"))
            throw new SyntaxError("Array traverse with for-in-loop, touching Array.prototype's 'error' property :-)");
    }
});

您可以将其添加为所有域的油脂猴子脚本,并且几乎在每个站点上都会看到警报:-)多数是由对带有可疑参数btw的jQuery.extend调用引起的.

You can add it as a greasemonkey script for all domains, and you will see alerts on nearly every site :-) Most of them are caused by calls to jQuery.extend with questionable arguments, btw.

我的问题现在是:是否存在任何使此类错误"循环合法的情况,或其他任何导致假阳性警报的情况?

My question is now: Are there any situations that legitimate such "wrong" loops, or anything else causing false-positive alerts?

我想知道这将如何影响我的代码的有用性.

I am wondering how this would affect the usefulness of my code.

是.合法性通常可以是主观的,但是...

Yes. Legitimacy can often be subjective, but...

作为一个例子,也许我有一个稀疏数组,在这里我仅在具有数据的索引处设置值:

As an example, perhaps I have a sparse array, where I have only set values at the indexes with data:

var a = [];
a[123123] = "foo";
a[1233123] = "bar";

如果我想遍历在此数组中定义的元素,则可以使用for...in构造.即使我进行了防御性编码,您的脚本仍会触发(误报)...

If I wanted to iterate over the elements that I defined in this array, then I would use the for...in construct. Even if I coded it defensively, your script would still trigger (a false positive)...

for (var prop in a) {
  if (a.hasOwnProperty(prop)) {
    // this is a legitimate array element
  }
}

另请参见为什么要使用"for ... in"进行数组迭代是个坏主意吗?了解更多信息和意见.

See also Why is using "for...in" with array iteration a bad idea? for more information and opinions.