跟着 MDN 学JavaScript day_10:数组——数据的有序集合

引言

在本模块的最后一篇文章中,我们将深入探讨JavaScript中一个极其重要的数据结构------数组。数组提供了一种优雅的方式,让我们能够将一组相关的数据存储在单个变量名下。在编程的世界里,处理数据集合是最常见的任务之一,而数组正是为这一任务量身打造的工具。通过本文的学习,你将理解数组的本质,掌握如何创建数组,学会检索、添加和删除数组中的元素,并了解一些实用的数组方法。无论你是刚开始学习JavaScript的新手,还是希望巩固基础知识的开发者,这篇文章都将为你打下坚实的数组操作基础。


一、数组是什么------像列表一样的对象

数组通常被描述为"像列表一样的对象"。简单来说,数组是一个包含了多个值的对象。数组对象可以存储在变量中,并且能用和其他任何类型的值完全相同的方式处理,区别在于我们可以单独访问列表中的每个值,并利用数组执行一些有用且高效的操作,比如循环遍历数组中的每个元素并对其执行相同的操作。

让我们设想一个实际的场景:我们有一系列产品和价格需要处理。如果没有数组,我们必须将每个产品存储在一个单独的变量中,然后分别为每个产品调用打印代码、单独累加价格。这种做法不仅耗费时间,效率极低,而且容易出错。当只有10个产品时,这可能只是有些麻烦;但当产品数量增加到100个甚至1000个时,这种方式的弊端就暴露无遗了。而使用数组,我们可以轻松地存储所有这些产品,并通过循环一次性完成打印和统计工作。

这个产品处理的例子将贯穿我们的学习过程。现在,让我们先从数组的基础知识开始,通过在JavaScript控制台中输入一些示例来逐步理解数组的用法。


二、创建数组------方括号中的有序世界

数组由方括号构成,其中包含用逗号分隔的元素列表。创建一个数组就像列一张清单一样简单。假设我们想在数组中存储一个购物清单,可以这样编写代码:

javascript 复制代码
let shopping = ["bread", "milk", "cheese", "hummus", "noodles"];
shopping;

在这个例子中,数组中的每个项目都是一个字符串。但数组的强大之处在于它的灵活性:你可以将任何类型的元素存储在数组中------字符串、数字、对象、另一个变量,甚至可以嵌套另一个数组。不同类型的元素也可以混合存储在同一个数组中,它们不必全都是同一种数据类型。

javascript 复制代码
let sequence = [1, 1, 2, 3, 5, 8, 13];
let random = ["tree", 795, [0, 1, 2]];

sequence 数组中,我们存储了一个斐波那契数列,所有元素都是数字类型。而在 random 数组中,我们混合了字符串 "tree"、数字 795 以及一个嵌套数组 [0, 1, 2]。这种灵活性使得数组能够适应各种复杂的数据存储需求。建议你在继续学习之前,动手创建几个自己的数组,尝试不同的数据类型组合,加深对数组创建的理解。


三、访问和修改数组元素------从零开始的索引之旅

创建数组之后,我们需要能够访问其中的特定元素。JavaScript使用方括号表示法来访问数组元素,这与我们检索字符串中特定字符的方法完全一致。需要注意的一个重要概念是:计算机中的索引从0开始计数,这意味着数组的第一个元素索引为0,第二个元素索引为1,以此类推。

javascript 复制代码
shopping[0];
// returns "bread"

上面的代码访问了 shopping 数组的第一个元素,返回了字符串 "bread"。如果你想要修改数组中的某个元素,只需为该索引位置的元素赋予新值即可:

javascript 复制代码
shopping[0] = "tahini";
shopping;
// shopping will now return [ "tahini", "milk", "cheese", "hummus", "noodles" ]

通过这种方式,我们轻松地将购物清单中的 "bread" 替换成了 "tahini"

当数组中包含数组时,我们称之为多维数组 。访问多维数组中的元素需要将两组方括号链接在一起。例如,要访问 random 数组中第三个元素(即嵌套数组 [0, 1, 2])中的第三项,我们可以这样操作:

javascript 复制代码
random[2][2];

第一个方括号 [2] 定位到 random 数组的第三个元素(即内层数组),第二个方括号 [2] 进一步访问该内层数组的第三个元素。这种多维数组的结构在处理网格数据、矩阵等场景时非常有用。


四、获取数组长度------length属性的妙用

你可以通过使用 length 属性来获取数组的长度,也就是数组中有多少项元素。这与查找字符串长度的方法如出一辙。了解数组的长度是进行数组操作的基础,尤其是在循环遍历数组时,length 属性扮演着至关重要的角色。

javascript 复制代码
sequence.length;
// should return 7

上面的代码返回 7,表示 sequence 数组包含7个元素。length 属性最常见的用途是配合循环使用,遍历数组中的所有项。下面是一个典型的遍历示例:

javascript 复制代码
let sequence = [1, 1, 2, 3, 5, 8, 13];
for (let i = 0; i < sequence.length; i++) {
  console.log(sequence[i]);
}

这段代码的执行逻辑清晰地展示了循环与数组的配合方式:

  1. 首先从数组的元素编号 0 开始循环;
  2. 然后在元素编号等于数组长度的时候停止循环(对于这个包含7个元素的数组,当 i 等于 7 时终止循环,而数组的最后一个有效索引是 6);
  3. 在每次循环中,使用 console.log() 将当前元素打印到浏览器控制台。

这种方式适用于任何长度的数组,体现了数组在批量处理数据时的巨大优势。


五、字符串与数组之间的转换------split和join的魔法

在实际开发中,我们经常会遇到原始数据被包含在一个长长的字符串中的情况。此时,我们需要将这些有用的数据项分离成更有用的形式以便处理,比如将它们显示在数据表中。split() 方法正是为此而生,它将一个字符串按照指定的分隔符拆分成数组。

首先,我们在控制台中创建一个包含多个城市名称的字符串:

javascript 复制代码
let myData = "Manchester,London,Liverpool,Birmingham,Leeds,Carlisle";

现在,我们使用逗号作为分隔符来拆分这个字符串:

javascript 复制代码
let myArray = myData.split(",");
myArray;

执行后,myArray 变成了一个包含六个城市名称的数组。我们可以验证新数组的长度并从中检索特定的项目:

javascript 复制代码
myArray.length;
myArray[0];                      // the first item in the array
myArray[1];                      // the second item in the array
myArray[myArray.length - 1];     // the last item in the array

使用 myArray.length - 1 来访问最后一个元素是一种常见的技巧,因为长度总是比最后一个索引大1。

split() 相反的操作是 join() 方法,它将数组元素合并回一个字符串。join() 方法接受一个参数,用于指定连接元素的分隔符:

javascript 复制代码
let myNewString = myArray.join(",");
myNewString;

此外,还可以使用 toString() 方法将数组转换为字符串。toString()join() 更简单,因为它不需要参数,但灵活性也相对较低------它始终使用逗号作为分隔符。而使用 join() 则可以指定不同的分隔符,比如空格、短横线或其他任意字符,这为字符串的格式化提供了更多可能性。

javascript 复制代码
let dogNames = ["Rocket", "Flash", "Bella", "Slugger"];
dogNames.toString(); // Rocket,Flash,Bella,Slugger

六、添加和删除数组元素------四种核心方法的对比

掌握了数组的基本操作后,我们来看如何动态地添加和删除数组元素。JavaScript提供了四组核心方法来实现这些操作:push()pop() 作用于数组末尾,unshift()shift() 作用于数组开头。

首先准备一个测试数组,我们将使用上一节中创建的城市列表:

javascript 复制代码
let myArray = [
  "Manchester",
  "London",
  "Liverpool",
  "Birmingham",
  "Leeds",
  "Carlisle",
];

push() ------ 在末尾添加

push() 方法用于在数组末尾添加一个或多个元素。当方法调用完成时,它会返回数组的新长度,这个返回值可以存储在变量中以供后续使用:

javascript 复制代码
myArray.push("Cardiff");
myArray;
myArray.push("Bradford", "Brighton");
myArray;

var newLength = myArray.push("Bristol");
myArray;
newLength;

pop() ------ 从末尾删除

与之对应,pop() 方法用于从数组末尾删除最后一个元素,并返回被删除的元素:

javascript 复制代码
myArray.pop();
let removedItem = myArray.pop();
myArray;
removedItem;

unshift() 和 shift() ------ 在开头操作

unshift()shift() 的功能与 push()pop() 完全相同,只是它们的作用位置变成了数组的开头。

unshift() 在数组开头添加元素:

javascript 复制代码
myArray.unshift("Edinburgh");
myArray;

shift() 则从数组开头删除第一个元素并返回它:

javascript 复制代码
let removedItem = myArray.shift();
myArray;
removedItem;

四种方法对比总结

方法 操作位置 操作类型 返回值
push() 末尾 添加元素 数组的新长度
pop() 末尾 删除元素 被删除的元素
unshift() 开头 添加元素 数组的新长度
shift() 开头 删除元素 被删除的元素

这四组方法为数组的动态操作提供了全面的支持。选择使用哪一组方法取决于你的具体需求:是需要在数组末尾操作还是在数组开头操作。理解它们的区别和联系,能够帮助你在实际编程中做出更合适的选择。


七、实践案例:打印产品清单

理论讲解之后,让我们通过一个实际案例来巩固所学知识。这个案例模拟了打印发票的场景:我们需要将产品名称和价格打印出来,然后计算总价格并显示在底部。

案例的初始数据结构是一些字符串,每个字符串包含一个产品名称和一个冒号分隔的价格。我们的任务包括五个步骤:

  1. 将这些字符串转换为一个数组并存储在名为 products 的变量中;
  2. 修正 for 循环的条件测试,使其能够正确遍历整个 products 数组;
  3. 将当前数组项目拆分成名称和价格两个独立的部分,并将价格从字符串转换为数字;
  4. 在循环中累加每个产品的价格到 total 变量;
  5. 构造格式化的字符串来显示每个产品的信息。

这个案例综合运用了数组的创建、遍历、字符串分割、类型转换以及字符串拼接等多个知识点。通过完成这个实际任务,你能够亲身体验到数组在数据处理中的强大作用,以及循环遍历带来的效率提升。在实际开发中,类似的模式会频繁出现------从数据源读取数据、遍历处理每一项、累加计算结果、最终呈现格式化输出。


八、实践案例:维护最近5个搜索记录

另一个常见的数组应用场景是维护一个固定长度的历史记录列表。push()pop() 方法在这类场景中表现出色。想象一个动画场景中,由于性能或显示限制,你可能只需要同时显示50个背景图像对象。当新对象被添加到数组中时,可以从数组中删除较旧的对象以保持所需的数量。

在我们的案例中,我们将构建一个简化版的搜索记录功能。用户在搜索框中输入内容时,搜索词会被记录到列表中,列表始终保持5个最近的搜索词。当新的搜索词被添加到顶部时,如果列表长度超过5,最后一个项目会被自动删除。这需要我们在正确的位置使用数组方法:将当前输入值添加到数组开头,并在必要时删除数组末尾的旧记录。

这个案例展示了数组在实际Web应用中的典型用法。真实的搜索应用中,用户或许还能点击先前的搜索词来返回上一次搜索并查看实际结果。而这里我们保持逻辑简单,专注于数组操作的练习。这种固定长度的队列结构在很多场景中都有应用,比如浏览器的历史记录、最近打开的文件列表、聊天消息的缓存等等。


总结

通过本文的学习,我们系统地掌握了JavaScript数组的核心概念和操作方法。数组作为一种有序的数据集合,凭借其灵活性和强大的方法支持,成为了JavaScript编程中不可或缺的工具。

我们从数组的基本定义出发,理解了数组作为"像列表一样的对象"的本质。学习了如何用方括号创建数组,如何通过索引访问和修改数组元素,以及如何利用 length 属性获取数组长度。split()join() 方法让我们能够在字符串和数组之间自由转换,这在实际的数据处理中极为实用。push()pop()unshift()shift() 四组方法则分别从数组的末尾和开头提供了添加和删除元素的能力。通过两个实践案例,我们将这些知识点融会贯通,体验了数组在真实场景中的应用价值。

掌握数组之后,你会发现它们在JavaScript中随处可见,尤其是与循环配合使用时,能够高效地对数据集合中的每个元素执行相同的操作。在下一个模块中,我们将深入学习循环的更多知识,届时你会发现数组和循环是一对绝佳的搭档。在学习新知识之前,不妨给自己一些时间消化本文的内容,动手编写一些数组操作的代码,让这些概念真正内化为你的编程能力。


还在为 JavaScript 代码写得像"意大利面条"、逻辑混乱难以维护而头秃?收藏本文持续跟进,后续将系统分享 JS 高效语法糖、浏览器兼容与 Polyfill 实战、手写核心源码解析、常见坑点避雷指南,从基础语法到进阶逻辑一站式打通,助你快速提升前端开发硬实力!

相关推荐
程序员小羊!1 小时前
07Java IO 流
java·开发语言
广州华水科技1 小时前
如何利用单北斗变形监测实现大坝安全监测?
前端
hxy06011 小时前
Flutter showModalBottomSheet等弹窗宽度问题
前端·flutter
亦暖筑序1 小时前
Java 8老系统旁路接入AI Gateway:不升级JDK也能用AI
java·spring boot·aigc·企业架构·ai gateway
Wireless_wifi61 小时前
IPQ9574 + WiFi 7: Building the Foundation for Scalable Edge AI Deployments
前端·人工智能·edge
IT龟苓膏1 小时前
Java 集合进阶:ConcurrentHashMap、HashSet、LinkedHashMap、TreeMap 和 fail-fast 一篇讲清
java·开发语言·jvm
晓13131 小时前
【Cocos Creator 2.x】篇——第五章 游戏常用关键技术
前端·javascript·vue.js·游戏引擎
李白的天不白1 小时前
config/WebMvcConfig.java
开发语言·python
terry6001 小时前
2026企业级携号转网查询标准:论实时数据同步与高并发承载设计
java·大数据·人工智能·json·信息与通信·数据库架构