此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

View in English Always switch to English

索引集合

本章介绍按索引值排序的数据集合。包括数组和类数组结构,如 Array 对象和 TypedArray 对象。

数组是由名称和索引引用的值构成的有序列表。

例如,考虑一个名为 emp 的数组,它包含按数字雇员编号索引的雇员姓名。所以 emp[0] 是 0 号员工,emp[1] 是 1 号员工,以此类推。

JavaScript 中没有明确的数组数据类型。但是,你可以使用预定义的 Array 对象及其方法来处理应用程序中的数组。Array 对象具有以各种方式操作数组的方法,例如连接、反转和排序。它有一个用于确定数组长度的属性和用于正则表达式的其他属性。

在这篇文章中,我们将专注于数组,但许多相同的概念也适用于类型化数组,因为数组和类型化数组共享许多类似的方法。关于类型化数组的更多信息,请参见类型化数组参考

创建数组

以下语句创建了等效的数组:

js
const arr1 = new Array(element0, element1, /* … ,*/ elementN);
const arr2 = Array(element0, element1, /* … ,*/ elementN);
const arr3 = [element0, element1, /* … ,*/ elementN];

element0, element1, …, elementN 是数组元素的值列表。当指定这些值时,数组将用它们作为数组的元素初始化。数组的 length 属性被设置为参数的数量。

括号语法称为“数组字面量”或“数组初始化式”。它比其他形式的数组创建更短,因此通常是首选。详见数组字面量

为了创建一个长度不为 0,但是又没有任何元素的数组,可选以下任何一种方式:

js
// 这种方式...
const arr1 = new Array(arrayLength);

// ...与这种方式会形成相同数组
const arr2 = Array(arrayLength);

// 这个效果也一样
const arr3 = [];
arr3.length = arrayLength;

备注:以上代码,arrayLength 必须为一个 Number。否则,将会创建一个只有单个元素(内含提供的值)的数组。调用 arr.length 会返回 arrayLength,但数组不包含任何元素。for...in 循环在数组上找不到任何属性。

除了上面所示的新定义的变量外,数组还可以被赋值为新对象或现有对象的属性:

js
const obj = {};
// …
obj.prop = [element0, element1, /* … ,*/ elementN];

// 或
const obj = { prop: [element0, element1, /* … ,*/ elementN] };

如果你希望用单个元素初始化一个数组,而这个元素恰好又是 Number,那么你必须使用括号语法。当单个 Number 传递给 Array() 构造函数时,将会被解释为 arrayLength,并非单个元素。

js
// 创建一个只有唯一元素的数组:数字 42。
const arr = [42];

// 创建一个没有元素的数组,且数组的长度被设置成 42。
const arr = Array(42);

// 上面的代码与下面的代码等价:
const arr = [];
arr.length = 42;

如果 N 不是一个整数,调用 Array(N) 将会报 RangeError 错误,下面的例子说明了这种行为:

js
const arr = Array(9.3); // RangeError: Invalid array length

如果你需要创建任意类型的单元素数组,安全的方式是使用数组字面量。或者在向数组添加单个元素之前先创建一个空的数组。

你也可以使用 Array.of 静态方法来创建包含单个元素的数组。

js
const wisenArray = Array.of(9.3); // wisenArray 只包含一个元素:9.3

引用数组元素

因为元素也是属性,你可以使用属性访问器来访问。假设你定义了以下数组:

js
const myArray = ["Wind", "Rain", "Fire"];

你可以将数组的第一个元素引用为 myArray[0],将数组的第二个元素引用为 myArray[1],等等...元素的索引从零开始。

备注:你也可以使用属性访问器来访问数组的其他属性,就像对象一样。

js
const arr = ["one", "two", "three"];
arr[2]; // three
arr["length"]; // 3

填充数组

你可以通过给数组元素赋值来填充数组,例如:

js
const emp = [];
emp[0] = "Casey Jones";
emp[1] = "Phil Lesh";
emp[2] = "August West";

备注:如果你在以上代码中给数组运算符的是一个非整型数值,那么它将作为一个表示数组的对象的属性创建,而不是数组的元素。

js
const arr = [];
arr[3.4] = "Oranges";
console.log(arr.length); // 0
console.log(Object.hasOwn(arr, 3.4)); // true

你也可以在创建数组的时候去填充它:

js
const myArray = new Array("Hello", myVar, 3.14159);
// 或
const myArray = ["Mango", "Apple", "Orange"];

理解 length

在实现层面,JavaScript 实际上是将元素作为标准的对象属性来存储,把数组索引作为属性名。

length 属性是特殊的,如果存在最后一个元素,则其值总是大于其索引的正整数(在下面的示例中,'Dusty' 的索引是 30,所以 cats.length 返回 30 + 1)。

记住,JavaScript 数组索引是基于 0 的:它们从 0 开始,而不是 1。这意味着 length 属性将比最大的索引值大 1:

js
const cats = [];
cats[30] = ["Dusty"];
console.log(cats.length); // 31

你也可以给 length 属性赋值。

写一个小于数组元素数量的值将截断数组,写 0 会彻底清空数组:

js
const cats = ["Dusty", "Misty", "Twiggy"];
console.log(cats.length); // 3

cats.length = 2;
console.log(cats); // [ 'Dusty', 'Misty' ] - Twiggy 已经被移除了

cats.length = 0;
console.log(cats); // 输出 [],猫名称的数组现在已经空了

cats.length = 3;
console.log(cats); // 输出 [ <3 empty items> ]

遍历数组

一种常见的操作是遍历数组的值,以某种方式处理每个值。最简单的方法如下:

js
const colors = ["red", "green", "blue"];
for (let i = 0; i < colors.length; i++) {
  console.log(colors[i]);
}

如果你确定数组中没有一个元素求值为 false(例如,如果你的数组只包含 DOM 节点),你可以选择一个更高效的土法子:

js
const divs = document.getElementsByTagName("div");
for (let i = 0, div; (div = divs[i]); i++) {
  /* 以某种方式处理 div */
}

这避免了检查数组长度的开销,并确保 div 变量在每次循环时都被重新赋值给当前项,从而增加了便利性。

forEach() 方法提供了遍历数组元素的其他方法:

js
const colors = ["red", "green", "blue"];
colors.forEach((color) => console.log(color));
// red
// green
// blue

传递给 forEach 的函数对数组中的每个元素执行一次,数组元素作为参数传递给该函数。未赋值的值不会在 forEach 循环迭代。

注意,在数组定义时省略的元素不会在 forEach 遍历时被列出,但是手动赋值为 undefined 的元素是被列出的: