为什么如果数组是稀疏的,array.indexOf(undefined) 就不起作用了?

12

我是JavaScript的新手,有一件事情困扰着我。我有一个非常简单的代码:

var a = [];
a[1] = 1;

i = typeof(a[0]);
index = a.indexOf(undefined);
len = a.length;

console.log(a);
console.log("\n" + len);
console.log("\n" + i);
console.log("\n" + index);

我的问题是:为什么indexOf返回-1而不是0?我知道这个方法使用===进行比较,但我将undefined关键字用作参数。如果我将方法参数更改为"undefined",它也无法工作(但对我来说这很明显)。有人能解释一下这个问题,并告诉我在数组中找到undefined值的最简单方法是什么吗?


undefined 是 JavaScript 中的原始类型,因此它是独立的。当你有一个不存在的空索引时,直到你给它分配了某些东西,它才存在。因此,当 indexOf() 在数组中查找 undefined 时,实际上是在寻找该值。如果它为数组中每个未填充的索引返回一个值,那么它将永远继续下去。 - JmJ
可能是重复的问题:如何在数组中找到缺失值的索引? - djechlin
如上所述,undefined 有点不准确,实际上它是一个特定的原始值,因此它实际上是已定义的,而不是字面上的未定义,当您拥有具有未设置索引的数组时就会出现这种情况。 - adeneo
谢谢您的回复!现在一切都清楚了! - JohnDoe
2个回答

13

实际上,这将在一个数组中查找一个undefined值,问题在于您的数组a中没有任何undefined值,因此它返回-1,表示未找到。 您的数组如下所示:

[*未初始化*, 1]

事实上,将什么都不放在第一个位置并不意味着它填充了一个undefined,它只是未初始化/不存在。

如果您执行以下操作:

var a = [undefined, 1];
var index = a.indexOf(undefined);
console.log(index);

它实际上会按预期打印出0

编辑:要回答你如何找到未初始化的值的问题,请执行以下操作

var a = [];
a[1] = 1;

for(var i = 0; i < a.length; i++){
    if(a[i] === undefined){
      console.log(i);
    }
}

这将打印未初始化数组值的索引。之所以这实际上能够工作,而不像 indexOf 那样是因为如果:a[i] 的值为 undefined

(1) 元素存在且其值为 undefined,或者

(2) 该元素根本不存在。indexOf 会跳过数组中的这些“空洞”。


我想补充一下,如果原帖的目标是尝试找到他尚未分配值的第一个索引,他可以使用循环并以这种方式检查。 - dustinroepsch

4

一般来说,JavaScript 中的数组是稀疏的,它们可以有空洞(这就是为什么indexOf()返回-1的原因),因为数组只是从索引到值的映射。您要查找的数组称为密集的,它看起来像:

var a = Array.apply(null, Array(3)) 

或者
var a = Array(undefined, undefined, undefined) 
a.indexOf(undefined) //0

请查看this文章,希望它能对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接