数组中的孔与undefined和map函数

时间:2015-02-14 16:54:02

标签: javascript arrays

我理解数组上的map is not called on undefined indexes并且我理解未定义的索引不同于明确分配了未定义的数组索引。价值(它是,不是吗?)。然而,如何区分数组中的空洞和undefined值?

以下代码:

foo.js

var arr = [,,undefined,,,,3,,,4];
console.log("A hole the same as undefined? "+(arr[0]===undefined?"yes":"no"));
var _ignored = arr.map(function(x) {console.log("f called on ["+x+"]");});  

...在跑步时产生:

$ node foo.js 
A hole the same as undefined? yes
f called on [undefined]
f called on [3]
f called on [4]

...将map替换为forEach时,会有类似的结果。

2 个答案:

答案 0 :(得分:6)

in运算符会告诉您索引是否已实际分配给:

a = []
a[5] = window.foo

document.write(a[4] + "<br>")
document.write(a[5] + "<br>")

document.write((4 in a) + "<br>")
document.write((5 in a) + "<br>")

Javascript数组实际上是具有特殊length属性的对象,而数组索引只是属性名称(事实上,它们甚至是字符串,而不是内部的数字)。所以上面的定义相当于:

a = {
  5: window.foo,
  length: 6
}

因此,与键相关的所有对象功能(如inhasOwnPropertyObject.keys)也适用于数组索引。

forEach和其他迭代方法work by iterating from 0 to length-1 and checking if n-th index is actually present in the argument,他们不“知道”参数实际上是数组还是只是一个通用对象:

a = {1:'one', 5:'five', length:100};

[].forEach.call(a, function(x) {
  document.write(x)
});

答案 1 :(得分:-1)

你所谓的“洞”并不是一个洞:

var a = [,,,,,,,,,,];
a.length;  // 10
var n, k;
n=0; for (k in a){if (a.hasOwnProperty(k)){++n;}else{break;}};
n; // 10 : a has 10 own properties, all SET to undefined

现在删除所有属性,并重新计算

while (n--) delete a[n];
for (k in a){if (a.hasOwnProperty(k)){++n;}else{break;}};
n; // 0
a.length; // 10 : a is identical to Array(10), empty array of length 10

要获取带有孔的数组,您可以手动删除属性,或者使用Array(N)开始并使用值填充一些索引,或使用push / splice但不使用返回数组的方法。例如:

Array(2).concat([void(0)]).concat(Array(3)).concat([3]).concat(Array(2)).concat([4]);

完全重现你的原始数组(它有10个长度和10个自己的属性),虽然第一个summand(Array(2))没有。


编辑:以上是在ExtendScript中测试的,在最近的浏览器中并不是这样(参见评论)。之后在Firefox中测试过并且[,,,,,,]确实没有自己的属性......