JavaScript 数组手册 – 通过示例和备忘单了解 JS 数组方法如何工作

93 阅读10分钟

在编程中,数组是包含元素集合的数据结构。数组非常有用,因为您可以在单个数组中存储、访问和操作多个元素。

在本手册中,您将学习如何在 JavaScript 中使用数组。我们将介绍创建数组时需要遵循的特定规则,以及如何使用数组方法根据需要操作和转换数组。

目录

  1. JavaScript 中数组的工作原理
  2. 如何在 JavaScript 中创建数组
  3. 如何访问数组的元素
  4. 数组长度属性
  5. 如何向数组添加元素
  6. 如何从数组中删除元素
  7. 如何检查变量是否是数组
  8. 如何迭代或循环数组
  9. 如何将数组转换为字符串
  10. 如何比较两个数组
  11. 如何复制数组
  12. 如何将两个数组合并为一个
  13. 如何搜索数组
  14. 如何对数组进行排序
  15. 如何创建多维数组
  16. JavaScript 数组方法备忘单
  17. 包起来

JavaScript 中数组的工作原理

在 JavaScript 中,数组被实现为一个对象,该对象可以将一组项目、元素或值作为有序集合。这意味着您可以使用数组中的元素在集合中的位置来访问该元素。在下一节中您将了解为什么这很重要。

数组可以容纳不同数据类型的元素,并且数组的大小不固定。这意味着您可以根据需要向数组添加任意数量的元素。

如何在 JavaScript 中创建数组

在 JavaScript 中创建数组有两种方法:

  • 使用方括号[]
  • 使用Array()构造函数

方括号[]是用于创建数组的文字表示法。数组元素在方括号内定义,每个元素使用逗号分隔,

以下示例演示如何创建名为 的数组,myArray该数组包含三个不同类型的元素:数字、字符串和布尔值。

let myArray = [29, 'Nathan', true];

以下是创建包含 3 个数字元素的数组的方法:

let myNumbers = [5, 10, 15];

您可以在方括号内指定任意数量的元素。

创建数组的另一种方法是使用Array()构造函数,其工作方式类似于方括号:

let myArray = Array(29, 'Nathan', true);

// or
let myNumbers = new Array(5, 10, 15);

请注意,可以使用或不使用new运算符来调用构造函数。两者都创建了一个数组对象就好了。

在大多数代码示例和代码库中,您很可能会看到开发人员使用方括号来创建数组,而不是使用构造函数。这是因为打字[]比打字更快Array()

如何访问数组的元素

正如我之前所说,数组是一个有序集合,因此您可以从数组中的位置(也称为索引号)访问元素。

要访问数组的元素,您需要指定数组名称,后跟方括号。在方括号内,指定要访问的元素的索引。

例如,以下是访问 的第一个元素的方法myArray

let myArray = [29, 'Nathan', true];

console.log(myArray[0]); // 29
console.log(myArray[1]); // Nathan
console.log(myArray[2]); // true

数组索引号从 0 开始,每添加到数组中一个元素,索引号就加 1。

如果您尝试访问尚未分配任何值的索引号,JavaScript 将返回undefined如下所示:

let myArray = [29, 'Nathan', true];

console.log(myArray[3]); // undefined
console.log(myArray[4]); // undefined
console.log(myArray[100]); // undefined

您还可以使用赋值运算符将某个索引号上的元素替换为新元素=

以下示例显示如何将第三个元素(布尔值)替换为字符串:

let myArray = [29, 'Nathan', true];

// Replace the third element
myArray[2] = 'Sebhastian';

console.log(myArray); // [ 29, 'Nathan', 'Sebhastian' ]

在上面的示例中,您可以看到true布尔值被字符串“Sebhastian”替换。接下来我们就来看看楼盘吧length

数组length属性

length属性显示数组有多少个元素。您可以使用点.符号访问此属性,如下所示:

let myArray = [29, 'Nathan', true];

console.log(myArray.length); // 3

let animals = ['Dog', 'Cat'];

console.log(animals.length); // 2

length每次在数组中添加或删除元素时,该属性都会更新。

如何向数组添加元素

要将一个或多个元素添加到数组中,可以使用数组push()unshift()方法。

push()方法将新元素添加到数组末尾,而该unshift()方法将新元素插入数组开头:

let animals = ['Dog', 'Cat'];

animals.push('Horse', 'Fish');

console.log(animals);
// [ 'Dog', 'Cat', 'Horse', 'Fish' ]

animals.unshift('Bird');

console.log(animals);
// [ 'Bird', 'Dog', 'Cat', 'Horse', 'Fish' ]

在这里,请注意,您可以使用逗号来分隔要添加到数组中的元素。

接下来,让我们看看如何从数组中删除元素。

如何从数组中删除元素

要从数组中删除元素,您可以使用shift()pop()方法,具体取决于要删除的元素的位置。

使用该shift()方法删除数组中的第一个元素,并使用该方法pop()删除数组中的最后一个元素:

let animals = ['Dog', 'Cat', 'Horse', 'Fish'];

animals.shift();

console.log(animals);
// [ 'Cat', 'Horse', 'Fish' ]

animals.pop();

console.log(animals);
// [ 'Cat', 'Horse' ]

和一次只能删除一个元素shift()pop()如果要删除数组中间的元素,需要使用该splice()方法。

如何使用splice()删除或添加元素

数组splice()方法用于删除或添加特定位置的元素。push当、popshift、 和unshift无法完成工作时,可以使用此方法。

要使用该splice()方法删除元素,您需要指定两个参数:开始数组操作的索引号和要删除的元素数。

例如,假设您要删除animals数组中索引 1 和 2 处的两个元素。操作方法如下:

let animals = ['Dog', 'Cat', 'Horse', 'Fish'];

animals.splice(1, 2);

console.log(animals);
// [ 'Dog', 'Fish' ]

splice(1, 2)意味着从索引 1 开始数组操作,然后从那里删除 2 个元素。

要使用 添加元素splice(),您需要在第二个参数之后指定要添加的元素。

例如,这里我在索引 1 处添加字符串值“Bird”和“Squid”:

let animals = ['Dog', 'Cat'];

animals.splice(1, 0, 'Bird', 'Squid');

console.log(animals);
// [ 'Dog', 'Bird', 'Squid', 'Cat' ]

如果您不想删除任何元素,可以将其0作为第二个参数传递给该splice()方法。然后指定要添加的元素。

splice()第一次看到该方法时可能会感到困惑,但不用担心!通过更多的练习,你会记住它是如何工作的。

如何检查变量是否是数组

要检查变量是否是数组,可以使用 方法Array.isArray()来测试提供给该方法的参数是否是数组。

true当您向该方法传递一个数组时,此方法将返回,false对于其他任何事情:

let myArray = [1, 2, 3];
let notAnArray = 'Hello!';

console.log(Array.isArray(myArray)); // true
console.log(Array.isArray(notAnArray)); // false

Array注意,调用方法时需要指定类isArray()

这是因为它isArray()是一个静态方法,因此只能从定义该方法的类中直接调用它。

如何迭代或循环数组

在 JavaScript 中,有 4 种方法可以迭代数组,具体取决于您使用的方法:

  1. 使用for循环
  2. 使用while循环
  3. 使用for...in循环
  4. 使用for...of循环
  5. 使用forEach()方法

让我们通过示例来学习如何使用这 4 种方法。

1.如何使用for循环

要使用循环迭代数组for,您需要使用数组length作为条件表达式。

在下面的示例中,for只要变量i小于数组的长度,循环就会继续运行:

let animals = ['dog', 'bird', 'cat', 'horse'];

for (let i = 0; i < animals.length; i++) {
  console.log(animals[i]);
}

for您可以在循环体内操作数组的元素。

2. 如何使用while循环

迭代数组的另一种方法是使用循环while。您需要使用变量和数组的长度来控制迭代何时停止,就像for之前的循环一样:

let animals = ['dog', 'bird', 'cat', 'horse'];

let i = 0;

while (i < animals.length) {
  console.log(animals[i]);
  i++;
}

在 while 循环内,您需要将i变量加一以避免无限循环。

3. 如何使用 for...in 循环

循环for...in是另一种可用于迭代数组的语法。该循环返回数组的索引位置,因此您可以像这样使用它:

let animals = ['dog', 'bird', 'cat', 'horse'];

for (i in animals) {
  console.log(animals[i]);
}

for...inforor循环相比,该循环更简洁,但在迭代数组时while最好使用循环。for...of

4. 如何使用 for...of 循环

for...of循环可用于迭代数组。它在每次迭代中返回数组的元素:

let animals = ['dog', 'bird', 'cat', 'horse'];

for (element of animals) {
  console.log(element);
}

for...in循环返回索引位置时,for...of循环直接返回元素。

5. 使用forEach()方法

JavaScript 数组对象本身有一个名为 的方法forEach(),您可以使用该方法从位置 0 到最后一个位置迭代数组。

该方法接受在每次迭代中执行的回调函数。对于每次迭代,该方法还传递数组的元素和索引位置。下面是使用该方法的示例:

let animals = ['dog', 'bird', 'cat', 'horse'];

animals.forEach(function (element, index) {
  console.log(`${index}: ${element}`);
});

输出将是:

0: dog
1: bird
2: cat
3: horse

这就是使用该方法迭代数组的方式forEach()。您可以使用您最喜欢的任何方法。

如何将数组转换为字符串

要将数组转换为字符串,可以使用toString()orjoin()方法。

toString()方法将给定数组转换为字符串,元素之间用逗号分隔:

const animals = ['cat', 'bird', 'fish'];

console.log(animals.toString()); // "cat,bird,fish"

join()方法还将数组转换为字符串,但您可以传递特定的字符串分隔符作为其参数。

以下示例显示如何使用斜杠/和空字符串作为字符串分隔符:

const animals = ['cat', 'bird', 'fish'];

console.log(animals.join()); // "cat,bird,fish"

console.log(animals.join('/')); // "cat/bird/fish"

console.log(animals.join('')); // "catbirdfish"

在幕后,该toString()方法实际上调用了join()创建字符串的方法。

如何比较两个数组

JavaScript 数组被视为对象。因此,当您比较两个数组时,比较将查看引用(即存储该​​数组的内存位置的地址),而不是实际值。

false即使两个数组包含相同的元素,它们的比较也会返回:

let arrayOne = [7, 8, 9];
let arrayTwo = [7, 8, 9];

console.log(arrayOne === arrayTwo); // false

这是因为arrayOnearrayTwo是存储在不同内存位置的不同对象。

数组比较返回的唯一方法true是当两个变量引用同一个数组对象时。在下面的示例中,arrayTwo变量是对 的引用arrayOne

let arrayOne = [7, 8, 9];
let arrayTwo = arrayOne;

console.log(arrayOne === arrayTwo); // true

但是,当您需要比较来自不同引用的两个数组时,这将不起作用。比较数组的一种方法是将数组转换为 JSON 对象。

通过将数组转换为 JSON 对象来比较数组

在比较两个不同的数组之前,需要通过调用该JSON.stringify()方法将它们转换为 JSON 对象。

然后您可以比较两个序列化的字符串,如下所示:

let arrayOne = [7, 8, 9];
let arrayTwo = [7, 8, 9];

console.log(JSON.stringify(arrayOne) === JSON.stringify(arrayTwo)); // true

但此解决方案间接比较数组,并且不同顺序的相同值将返回false而不是true.

要以编程方式比较两个数组的元素,您需要使用另一种解决方案。

如何使用every()方法比较数组

比较两个数组的另一种方法是使用length属性和every()方法的组合。

true首先,比较数组的长度,以便当第二个数组包含的元素多于第一个数组时,比较不会返回。

之后,您测试第一个数组上的元素是否等于第二个数组上相同索引位置的元素。使用&&运算符加入比较,如下所示:

let arrayOne = [7, 8, 9];
let arrayTwo = [7, 8, 9];

let result =
  arrayOne.length === arrayTwo.length &&
  arrayOne.every(function (element, index) {
    // compare if the element matches in the same index
    return element === arrayTwo[index];
  });

console.log(result); // true

这样,您可以比较特定索引处的元素是否确实相等。

尽管如此,此解决方案要求两个数组在某个索引处具有相同的元素才能返回true.

如果您不关心顺序,只希望两个数组具有相同的元素,则需要使用该includes()方法而不是相等===运算符。

如何使用includes()方法比较数组

为了比较无序的数组元素,可以使用every()includes()方法的组合。

includes()方法测试数组是否具有您指定为其参数的特定元素:

let arrayOne = [7, 8, 9];
let arrayTwo = [9, 7, 8];

let result =
  arrayOne.length === arrayTwo.length &&
  arrayOne.every(function (element) {
    return arrayTwo.includes(element);
  });

console.log(result); // true

该方法的另一种替代方法includes()是使用该indexOf()方法,该方法返回指定元素的索引。

当未找到该元素时,该indexOf()方法返回-1。这意味着您需要在如下所示的情况下every()退货:true``indexOf(element) !== -1

let arrayOne = [7, 8, 9];
let arrayTwo = [9, 7, 8];

let result =
  arrayOne.length === arrayTwo.length &&
  arrayOne.every(function (element) {
    return arrayTwo.indexOf(element) !== -1;
  });

console.log(result); // true

正如您所看到的,比较数组并不简单。您需要创造性地使用数组对象提供的方法。

但别担心!大多数时候,开发 Web 应用程序时不需要比较数组对象。接下来,让我们学习如何复制数组。

如何复制数组

复制数组的一种方法是使用slice()专门为复制数组而提供的方法。

您只需调用该方法并将返回的数组分配给一个新变量,如下所示:

let arrayOne = [7, 8, 9];
let arrayTwo = arrayOne.slice();

console.log(arrayOne); // [ 7, 8, 9 ]
console.log(arrayTwo); // [ 7, 8, 9 ]

但请记住,该slice()方法返回浅表副本,这意味着副本的值是对原始数组的引用。

当数组包含字符串、数字或布尔值等原始值时,浅复制不会导致问题。但当您复制对象数组时,这可能会成为问题。

为了向您展示我的意思,请参阅下面的示例:

let arrayOne = [{ name: 'Jack', age: 25 }];
let arrayTwo = arrayOne.slice();

console.log(arrayOne); // [ { name: 'Jack', age: 25 } ]
console.log(arrayTwo); // [ { name: 'Jack', age: 25 } ]

arrayTwo[0].name = 'Nathan';

console.log(arrayOne); // [ { name: 'Nathan', age: 25 } ]
console.log(arrayTwo); // [ { name: 'Nathan', age: 25 } ]

你注意到出了什么问题吗?上面的代码只修改了name的属性arrayTwo,但它改变了两个数组!

这是因为arrayTwo是 的浅拷贝arrayOne。为了防止这种行为,您需要执行深层复制,以便将arrayTwo值与原始数组断开连接。

如何创建数组的深层副本

要创建数组的深层复制,需要使用JSON.parse()JSON.stringify()方法而不是使用slice()方法来复制数组。

JSON.stringify()数组转换为 JSON 字符串,然后JSON.parse()将该字符串转换回数组。

由于副本是从 JSON 字符串创建的,因此不再与原始数组有连接:

let arrayOne = [{ name: 'Jack', age: 25 }];
let arrayTwo = JSON.parse(JSON.stringify(arrayOne));

console.log(arrayOne); // [ { name: 'Jack', age: 25 } ]
console.log(arrayTwo); // [ { name: 'Jack', age: 25 } ]

arrayTwo[0].name = 'Nathan';

console.log(arrayOne); // [ { name: 'Jack', age: 25 } ]
console.log(arrayTwo); // [ { name: 'Nathan', age: 25 } ]

在这里,您可以看到更改 的属性arrayTwo不会更改 中的相同属性arrayOne。干得好!

如何将两个数组合并为一个

JavaScript 提供了一种concat()方法,可用于将两个或多个数组合并为一个。以下示例演示如何将catsbirds数组合并为一个名为 的数组animals

let cats = ['tiger', 'cat'];
let birds = ['owl', 'eagle'];

let animals = cats.concat(birds);

console.log(animals); // [ 'tiger', 'cat', 'owl', 'eagle' ]
console.log(cats); // [ 'tiger', 'cat' ]
console.log(birds); // [ 'owl', 'eagle' ]

乍一看,该concat()方法的语法似乎是将birds数组合并到cats数组中。但从控制台日志中可以看到,cats数组实际上没有变化。

为了使代码更直观,您可以concat()从空数组而不是cats数组中调用该方法:

let cats = ['tiger', 'cat'];
let birds = ['owl', 'eagle'];

let animals = [].concat(cats, birds);

虽然这种语法更直观,但您很可能会cats.concat(birds)在许多 JavaScript 源代码中遇到这种语法。使用哪种语法?这由您和您的团队决定。

concat()方法允许您根据需要合并任意数量的数组。以下示例将三个数组合并为一个:

let cats = ['tiger', 'cat'];
let birds = ['owl', 'eagle'];
let dogs = ['wolf', 'dog'];

let animals = [].concat(cats, birds, dogs);
console.log(animals); // [ 'tiger', 'cat', 'owl', 'eagle', 'wolf', 'dog' ]

您现在已经了解了如何使用该concat()方法合并数组。接下来让我们看看如何使用扩展运算符合并数组。

如何使用扩展运算符合并数组

扩展运算符...可用于扩展要合并的数组的元素。您需要将扩展​​的元素放入一个新数组中,如下所示:

let cats = ['tiger', 'cat'];
let birds = ['owl', 'eagle'];

let animals = [...cats, ...birds];
console.log(animals); // [ 'tiger', 'cat', 'owl', 'eagle' ]

cats在这里,您可以看到和数组中的元素birds被扩展为另一个数组,并且该数组被分配为变量的值animals

concat()方法和扩展运算符都可以用来合并多个数组。

如何搜索数组

您可以通过三种方式搜索数组,具体取决于您想要实现的结果:

  1. 查找数组中是否存在某个元素
  2. 查找数组中元素的索引位置
  3. 查找数组中满足特定条件的值

让我们一起学习搜索数组的三种方法。别担心,它们很简单。

1.如何判断数组中是否存在某个元素

如果只想知道数组中是否存在某个元素,可以使用该includes()方法。以下示例在字符串数组中搜索字符串值“e”:

let letters = ['a', 'b', 'c', 'd'];

console.log(letters.include('e')); // false

当找到或未找到元素时,该includes()方法返回。true``false

2. 如何查找数组中元素的索引位置

其他时候,您可能想要获取元素的索引位置。indexOf()在这种情况下你需要使用该方法:

let letters = ['a', 'b', 'c', 'd'];

console.log(letters.indexOf('c')); // 2

这里,在数组indexOf()上调用该方法letters来搜索值“c”的索引。-1当未找到元素时该方法返回,但在本例中,它返回2为字母 c 位于第二个索引处(请记住,JS 使用从零开始的索引,这意味着计数从 0 开始,而不是 1)。

3. 如何在数组中查找满足一定条件的元素

要查找满足特定条件的元素,您需要使用该filter()方法。

filter()方法是可用于 JavaScript 数组对象的内置方法,可以帮助您过滤数组。该方法的语法如下:

arrayObject.filter(callback, thisContext);

该方法有两个参数:

  • callback(必需) – 将对每个数组值执行的过滤函数
  • thisContext可选this)-中关键字的值callback

thisContext参数是可选的,通常不需要。您只需要定义该callback函数,该函数将接受三个参数:

  • 正在currentElement被处理成方法
  • index开始于的元素的0
  • array你调用的对象filter()
filterCallback(currentElement, index, array){
  // ...
}

true回调函数必须包含返回或 的验证模式false

过滤方法示例

让我们看一个filter()实际的例子。假设您有一个名为stockPrices以下的数组:

let stockPrices = [3, 7, 2, 15, 4, 9, 21, 14];

您想要过滤价格以仅包含大于 5 的价格。

以下是使用该filter()方法的操作方法:

let stockPrices = [3, 7, 2, 15, 4, 9, 21, 14];

let filteredPrices = stockPrices.filter(function (currentElement) {
  return currentElement > 5;
});

console.log(filteredPrices); // [7, 15, 9, 21, 14]

filter()方法计算currentElement并返回truefalse

如果你的回调函数返回truecurrentElement将会被添加到结果数组中:

  • 在第一次迭代期间,回调currentElement返回3``false
  • 在第二次迭代期间,回调返回并将currentElement值推入结果数组7``true
  • 迭代将继续到最后一个元素
  • 结果数组被分配给filteredPrices变量

这就是该方法的工作原理。接下来,我们看看如何使用该filter()方法来过滤对象数组。

如何过滤对象数组

filter()方法还可以用于对象数组。

假设您有一个包含虚构股票价格及其符号的对象数组,如下所示:

let stocks = [
  {
    code: 'GOOGL',
    price: 1700,
  },
  {
    code: 'AAPL',
    price: 130,
  },
  {
    code: 'MSFT',
    price: 219,
  },
  {
    code: 'TSLA',
    price: 880,
  },
  {
    code: 'FB',
    price: 267,
  },
  {
    code: 'AMZN',
    price: 3182,
  },
];

现在您需要过滤数组以仅包含price价值小于 1000 的股票。具体操作方法如下:

let filteredStocks = stocks.filter(function (currentElement) {
  return currentElement.price < 1000;
});

的值filteredStocks如下:

0: {code: "AAPL", price: 130}
1: {code: "MSFT", price: 219}
2: {code: "TSLA", price: 880}
3: {code: "FB", price: 267}

最后,您还可以使用箭头函数语法编写回调函数,如下所示:

let filteredStocks = stocks.filter(
  currentElement => currentElement.price < 1000
);

当您有简单的过滤条件时,使用箭头函数语法可以帮助您编写更清晰的代码。

如何对数组进行排序

要对数组进行排序,可以使用提供的sort()方法,默认情况下按升序对数组进行排序:

let numbers = [5, 2, 4, 1];

numbers.sort();

console.log(numbers); // [ 1, 2, 4, 5 ]

如果要对数组进行降序排序,可以在该方法reverse()之后调用该方法sort(),如下所示:

let numbers = [5, 2, 4, 1];

numbers.sort().reverse();

console.log(numbers); // [ 5, 4, 2, 1 ]

reverse()方法将反转数组,因此第一个数组元素变为最后一个,最后一个变为第一个,依此类推。

如何创建多维数组

多维数组是一个包含另一个数组的数组。要创建一个,您需要在数组文字(方括号)内写入一个数组

以下示例展示了如何创建二维数组:

let numbers = [[5, 6, 7]];

要访问数组,只需使用两个数组索引调用变量即可。第一个索引用于外部数组,第二个索引用于内部数组:

let numbers = [[5, 6, 7]];
console.log(numbers[0][0]); // 5
console.log(numbers[0][1]); // 6
console.log(numbers[0][2]); // 7

从上面的示例中可以看出,该数组[5, 6, 7]存储在0外部[]数组的索引内。您可以在数组中添加更多元素,如下所示:

let numbers = [[5, 6, 7], [10], [20]];
console.log(numbers[1][0]); // 10
console.log(numbers[2][0]); // 20

如上所示,多维数组不需要具有相同的数组长度。尽管您甚至可以创建三维或四维数组,但不建议创建二维以上的数组,因为这会造成混乱。

[23]请注意,读取和访问下面的三维数组内的值是多么困难:

let numbers = [[5, 6, 7, [23]]];
console.log(numbers[0][3][0]); // 23

最后,您仍然可以使用 JavaScriptArray对象方法,如push()shift()、 和unshift()来操作多维数组:

let numbers = [[5, 6, 7, [23]]];
numbers.push([50]);
console.log(numbers); // [[5, 6, 7, [23]], [50]]

numbers.shift();
console.log(numbers); // [[50]]

numbers.unshift('13');
console.log(numbers); // ["13", [50]]

与一维数组相比,多维数组没有独特的方法。通常,它用于将一组相关数据存储为一个数组。

以下示例展示了如何对多维数组下的值进行name分组:age

let users = [  ['Nathan', 28],
  ['Jack', 23],
  ['Alex', 30],
];

除非必须使用数组,否则最好使用对象数组来存储一组相关数据:

let users = [
  { name: 'Nathan', age: 28 },
  { name: 'Jack', age: 23 },
  { name: 'Alex', age: 30 },
];

理想情况下,您应该在项目中仅使用一维数组。如果确实需要,请使用二维结构,但切勿超出范围,否则稍后操作数组将遇到困难。

JavaScript 数组方法备忘单

初学者通常会对数组拥有的方法数量感到不知所措,因此我准备了一份备忘单,可以帮助您快速查找方法的用途。