请考虑以下代码片段:
> a = [1, undefined, undefined, undefined, 3]
[1, undefined, undefined, undefined, 3]
> b = [1,,,,3]
[1, undefined × 3, 3]
> 1 in a
true
> 1 in b
false
我是否遗漏了什么?看起来,根据我如何定义数组中的 undefined
元素,in
运算符的行为会有所不同。
请考虑以下代码片段:
> a = [1, undefined, undefined, undefined, 3]
[1, undefined, undefined, undefined, 3]
> b = [1,,,,3]
[1, undefined × 3, 3]
> 1 in a
true
> 1 in b
false
我是否遗漏了什么?看起来,根据我如何定义数组中的 undefined
元素,in
运算符的行为会有所不同。
数组其实就是普通的 JavaScript 对象,只不过有一些专门的特性。引用自 ECMA 5.1 规范中的 Array Objects 部分:
数组对象对某种类型的属性名给予了特殊处理。当且仅当 ToString(ToUint32(P)) 等于 P 且 ToUint32(P) 不等于 232−1 时,属性名 P(以字符串形式表示)就是一个 数组下标。
所以说,数组下标就是数组对象的属性。现在,让我们来看一下数组中缺失元素的情况。
引用自 ECMA 5.1 标准规范:
数组元素可以省略在元素列表的开始、中间或结尾。每当元素列表中的逗号未被赋值表达式(即在另一个逗号之前或在开头的逗号)所跟随时,省略的数组元素将会增加数组长度并增加后续元素的下标。被省略的数组元素没有定义。如果数组末尾省略了元素,则该元素不会增加数组长度。
所以,当你说:
b = [1,,,,3];
除了元素1和3之外,其余元素都被视为数组中的缺失元素。现在,元素1和3对应于属性0和4(JavaScript中的数组索引从0开始)。console.log(Object.getOwnPropertyNames(b));
# [ '0', '4', 'length' ]
console.log(Object.getOwnPropertyNames(a));
# [ '0', '1', '2', '3', '4', 'length' ]
只有索引 0
和 4
在 b
中。你可能会想知道为什么 a
从索引 0
到 4
都有属性,但值是 undefined
。因为在索引 1、2 和 3 处的元素被定义为 undefined
,而在 b
中,我们不知道这些值是什么。这就是为什么它们没有被分配到属性(索引)上。
现在,您正在使用 in
运算符检查 1
是否在 b
中。引用自 in
运算符 MDN Doc,
如果指定的属性存在于指定的对象中,则 in 运算符返回 true。
所以,您基本上在检查 1
是否是 b
的一个属性,但它不是。这就是为什么 '1'
in b
返回 false
。
如果您想知道 1
是否在数组中,您应该使用 Array.prototype.indexOf
,像这样:
console.log(a.indexOf(1));
# 0
console.log(b.indexOf(1));
# 0
console.log(b.indexOf(5));
# -1
Array.prototype.indexOf
如果要查找的元素不在数组中,则返回-1
。因此,您可能希望执行以下操作
console.log(a.indexOf(1) !== -1);
# true
console.log(b.indexOf(1) !== -1);
# true
console.log(a.indexOf(5) !== -1);
# false
in
运算符而不是[].indexOf
)寻找“键”...也许并非如此。 - Ianundefined
”的概念——许多人似乎会忽略这种区别。 - Niet the Dark Absol,,,
的情况下,位置1处的元素被视为未声明。没有该名称的属性。 - Benjamin Gruenbaum//-1 means not in the list
//['a','b','c'].indexOf('a') is return index if not find in the list then it give -1.
if(['a','b','c'].indexOf('d') == -1)
{
console.log('yes it -1')
}
[undefined x 1]
”是什么? - Bergi