为什么带有逗号但没有元素的数组文字的长度不为0?

Rea*_*eal 17 javascript

我只是在摆弄一些JS,发现了一些我认为不会发生的事情.

var arr = [,];
arr.length // 1
arr[0] // undefined
Run Code Online (Sandbox Code Playgroud)

此外,[,,]长度为2.这些数组的长度不应该为0吗?我以为逗号只用于分隔数组中的元素,为什么看起来逗号被视为这些特定数组中的元素?数组的这种行为是否有任何类型的应用程序?

Bar*_*mar 44

在数组文字中,末尾的逗号被忽略,但所有其他逗号分隔元素.如果省略元素的值,则默认为undefined,但元素仍然存在.所以

[,]
Run Code Online (Sandbox Code Playgroud)

相当于

[undefined,]
Run Code Online (Sandbox Code Playgroud)

这相当于

[undefined]
Run Code Online (Sandbox Code Playgroud)

这有1个元素,其值为undefined.

同样

[,,] = [undefined, undefined, ] = [undefined, undefined]
Run Code Online (Sandbox Code Playgroud)

它有2个元素.

当您想要省略数组中间的元素时,默认元素行为更有用.

[1, 2, 3, , , 6, 7, 8]
Run Code Online (Sandbox Code Playgroud)

实际上,创建未定义元素的两种方式之间存在细微差别.在Javascript中,数组实际上是一个对象,它具有一个length属性和属性,其名称是数组元素的索引.通常,如果一个阵列具有length = N,索引属性将所有从整数0N-1.但是当省略数组文字中的元素时,不会为该索引创建任何属性.

在大多数情况下,这个缺失的属性并不重要,因为访问对象的不存在的属性会返回undefined,就像您有一个值为的属性一样undefined.您只能使用类似hasOwnProperty或调用方法检测这些缺失的属性Object.keys.Javascript控制台使用类似这样的东西来显示数组中的间隙与显式undefined元素不同.

所以

Object.getOwnPropertyNames([1, 2, 3]) => ["0", "1", "2", "length"]
Object.getOwnPropertyNames([1, , 3, 4]) => ["0", "2", "3", "length"]
Object.getOwnPropertyNames([, , , , ]) => ["length"]
Run Code Online (Sandbox Code Playgroud)

忽略最后一个逗号的原因是你可以写:

[ 
    "foo",
    "bar",
    "baz",
    "quux",
]
Run Code Online (Sandbox Code Playgroud)

这使编辑更容易,因为您可以插入和删除行而无需特殊情况下的最后一个元素.


JMM*_*JMM 6

这叫做elision.它在数组中创建一个"洞"(稀疏数组).可能有一些我不知道并且已经忘记的应用程序,我现在唯一能想到的就是我在这里展示的那个:https://stackoverflow.com/a/29629588/1034448.

[,...Array(10)].map((x, i) => { /* range of `i` is 1 - 10 */ })
Run Code Online (Sandbox Code Playgroud)

[,,]不是等同于[undefined, undefined,].有一个很大的区别:迭代方法不包括省略索引的元素.示例:

var enumerated = [];

function callback (x, i) {
  enumerated.push(i);
}

[,,].forEach(callback);
console.log(enumerated); // logs []

[undefined, undefined,].forEach(callback);
console.log(enumerated); // logs [1, 2]
Run Code Online (Sandbox Code Playgroud)