在 David Flanagan 的 Javascript:权威指南第六版第 147 页中,作者讨论了使用 for..in 循环遍历数组时的警告,以下是引用(粗体是我的)
...For this reason you should not use a for/in loop on an array unless you include an additional test to filter out unwanted properties. You might use either of these tests:
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;
那么作者为什么要用这么复杂的表达方式呢?
我是不是漏掉了什么?
最佳答案
不,这里有一些会失败的例子:
float :
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.abs
和 Math.floor
调用所要防止的。
顺便说一句,对数组索引使用 for in 循环确实没有任何优势。我建议使用基于索引的循环。
关于javascript - 测试自己属性的晦涩方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33980690/