测试自有属性的模糊方法

时间:2015-11-29 08:04:16

标签: javascript hasownproperty

在David Flanagan第147页的Javascript:权威指南第六版中,作者讨论了在使用for..in循环迭代数组时的警告,以下是引用(粗体是我的)

  

...出于这个原因,你不应该在数组中使用for / in循环,除非   您包含一个额外的测试来过滤掉不需要的属性。   您可以使用其中任何一种测试

for(var i in a) {
   if (!a.hasOwnProperty(i)) continue; // Skip inherited properties
   // loop body here
}

for(var i in a) {
   // Skip i if it is not a non-negative integer
   if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
}

现在第一个代码片段对我来说很清楚,将跳过继承的属性。

然而,第二个代码片段对我来说根本不清楚。

据我了解,第二个代码段将跳过数组的任何非数字属性(无论它是否属于自己的属性(与第一个代码片段不同))

但如果不是这样的话,你就不能使用简化的测试:

if (Number(i) != i) continue;

那么为什么作者使用这么复杂的表达呢?

我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:2)

不,这里有一些失败的例子:

浮点数:

var a = [1, 2, 3];
a['1.5'] = 'busted';
for(var i in a) {
    if (Number(i) != i) continue;
    document.getElementById('output1').textContent += i + '\n';
}
for(var i in a) {
    if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    document.getElementById('output2').textContent += i + '\n';
}
<h3>Number(i) != i</h3>
<pre id="output1"></pre>
<h3>String(Math.floor(Math.abs(Number(i)))) !== i</h3>
<pre id="output2"></pre>

负数:

var a = [1, 2, 3];
a['-5'] = 'busted';
for(var i in a) {
    if (Number(i) != i) continue;
    document.getElementById('output1').textContent += i + '\n';
}
for(var i in a) {
    if (String(Math.floor(Math.abs(Number(i)))) !== i) continue;
    document.getElementById('output2').textContent += i + '\n';
}
<h3>Number(i) != i</h3>
<pre id="output1"></pre>
<h3>String(Math.floor(Math.abs(Number(i)))) !== i</h3>
<pre id="output2"></pre>

这是Math.absMath.floor来电所守护的内容。

BTW,对于数组索引使用for in循环确实没有任何优势。我建议使用基于索引的循环。