JavaScript 数组是什么?
在之前的学习可以知道:一个变量可以存储一个值。比如想要存储一个字符串 "HTML",可以这样写:
const str = "HTML";如果我让你使用变量来存储 5 个字符串:"HTML"、"CSS"、"JavaScript"、"Vue"、"React",这个时候,大家会怎么写呢?不少小伙伴可能立马写出下面这样的代码:
const str1 = "HTML";
const str2 = "CSS";
const str3 = "JavaScript";
const str4 = "Vue";
const str5 = "React";写完之后,是不是觉得这种方式有点笨?假如我让你存储十几个甚至几十个字符串,那你岂不是每个字符串都要定义一个变量?跟之前 “JavaScript 函数” 是一样的道理,要是采用这种低级重复的语法,咱们 “程序猿(媛)” 早晚会累趴窝。
在 JavaScript 中,我们可以使用 “数组” 来存储一组 “相同类型”(一般情况下)的数据。数组本质上是一个对象,它是一种 “引用类型”,区别于我们在 “JavaScript 数据类型” 一节中介绍的 “基本类型” 。两者的区别在于:基本类型只有一个值,而引用类型可以包含多个值。
我们再回到例子中,像上面的一堆变量,使用数组实现如下:
const arr = ["HTML", "CSS", "JavaScript", "Vue", "React"];简单来说,我们可以用一个数组来保存多个值。现在来看,是不是感到清晰明了?如果想要得到数组的某一项,如 "JavaScript" 这一项,可以使用 arr[2] 来获取。
JavaScript 创建数组
在 JavaScript 中,我们可以使用 new 关键字来创建一个数组。创建数组,常见的有两种形式:一种是 “完整形式”;另外一种是 “简写形式”。
语法:
// 完整形式
const 数组名 = new Array(元素1, 元素2, ……, 元素n);
// 简写形式
const 数组名 = [元素1, 元素2, ……, 元素n];说明:
简写形式,是使用中括号 “[]” 括起来的。它其实就是一种快捷方式,在编程语言中一般又被称为 “语法糖”。
在实际开发中,我们更倾向于使用简写形式来创建一个数组。
const arr = []; // 创建一个空数组
const arr = ["HTML","CSS", "JavaScript"]; // 创建一个包含3个元素的数组语法糖与语法盐
语法糖(Syntactic sugar),是由英国计算机科学家彼得·约翰·兰达(Peter J.Landin)发明的一个术语。语法糖,指的是为计算机语言添加的一种语法,它不会影响语言的功能,但却可以带来很大的方便。我们可以将语法糖理解为一种某些功能的 “简写语法”。“语法糖” 的概念在 JavaScript 中非常常见。
语法盐(Syntactic salt),是一种可以降低程序员编写不良代码概率的语法,但代价是使得代码编写更加繁琐。这通常是在容易犯的错误上加上额外语法限制。“语法盐” 的概念在 C、C++ 中更常见。
JavaScript 访问数组的元素
在 JavaScript 中,想要获取数组某一项的值,我们都是使用 “下标” 的方式来获取。
const arr = ["HTML","CSS", "JavaScript"];上面表示创建了一个名为 “arr” 的数组,该数组中有 3 个元素(都是字符串):"HTML"、"CSS" 和 "JavaScript"。如果我们想要获取 arr 某一项的值,就可以使用下标的方式来获取。其中,arr[0] 表示获取第 1 项的值 "HTML"。arr[1] 表示获取第 2 项的值 "CSS",以此类推。
这里要重点说一下:数组的下标是从 0 开始的,而不是从 1 开始的。如果你以为获取第 1 项应该用 arr[1] 的话,那就理解错了。初学者很容易犯这种错误,一定要特别注意!
示例 1:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
// 创建数组
const arr = ["中国", "广东", "广州", "天河"];
// 获取元素
console.log(arr[3]);
</script>
</body>
</html>运行结果如下。
天河分析:
arr[3] 表示获取数组 arr 的第 4 个元素,而不是第 3 个元素!分析如下图所示。

JavaScript 修改数组的元素
获取数组的某一项的值我们是知道了,如果想要给某一个项赋一个新的值,或者给数组多增加一项,此时应该怎么做呢?其实也是通过数组下标来实现的。
语法:
arr[i] = 值; 示例 2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
const arr = ["HTML", "CSS", "JavaScript"];
arr[2] = "Vue"; // 修改第 3 个元素的值
console.log(arr[2]);
</script>
</body>
</html>运行结果如下。
Vue分析:
arr[2]="Vue" 表示给 arr[2] 重新赋值为 "Vue",也就是 "JavaScript" 被替换成了 "Vue"。此时,数组 arr 的值为:["HTML", "CSS", "Vue"]。由于之前 arr[2] 值已经被覆盖,所以 arr[2] 最终输出结果为 "Vue"。
示例 3:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
const arr = ["HTML", "CSS", "JavaScript"];
arr[3] = "Vue"; // 新增一个元素
console.log(arr);
</script>
</body>
</html>运行结果如下。
["HTML", "CSS", "JavaScript", "Vue"]分析:
在一开始,数组 arr 只有 3 项:arr[0]、arr[1]、arr[2]。由于我们使用了 arr[3] = "Vue",此时 arr 就多增加了一项。因此 arr 最终为:["HTML", "CSS", "JavaScript","Vue"]。
示例 4:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script>
const arr = [123, "javascript", false, NaN, undefined, null];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
</script>
</body>
</html>运行结果如下。
123
javascript
false
NaN
undefined
null分析:
不是说数组是存储一组 “相同数据类型” 的数据结构吗?为什么当数组元素为不同数据类型时,JavaScript 也不会报错并且能正确输出呢?
其实一个数组是可以存储 “不同数据类型” 的数据的,只不过我们极少那样做。一般情况下,都是用数组来存储 “相同数据类型” 的数据,所以这样理解就可以了。
JavaScript 数组方法
JavaScript 为数组(Array 对象)内置了非常多的方法,如下表所示。
| 静态方法 | |
| Array.isArray() | 判断值是否为数组 |
| Array.of() | 从参数创建新数组 |
| Array.from() | 从类数组或可迭代对象创建新数组 |
| 增删查改 | |
| unshift() | 在数组开头添加元素,返回新长度 |
| push() | 在数组末尾添加元素,返回新长度 |
| shift() | 移除并返回数组的第一个元素 |
| pop() | 移除并返回数组的最后一个元素 |
| 破坏性方法 | |
| reverse() | 反转数组元素顺序,修改原数组 |
| sort() | 对数组元素排序,修改原数组 |
| splice() | 添加或移除数组元素,修改原数组,返回移除元素 |
| toReversed() | 返回反转顺序的新数组,不修改原数组 |
| toSorted() | 返回排序后的新数组,不修改原数组 |
| toSpliced() | 返回添加或移除元素后的新数组,不修改原数组 |
| with() | 返回指定索引处更新元素后的新数组,不修改原数组 |
| 遍历数组 | |
| forEach() | 对数组每个元素执行指定函数,无返回值 |
| map() | 对数组每个元素应用函数,返回新数组 |
| filter() | 返回通过指定函数测试的元素组成的新数组 |
| reduce() | 从左到右对数组元素应用函数,累积为单个值 |
| reduceRight() | 从右到左对数组元素应用函数,累积为单个值 |
| keys() | 返回数组 “索引” 的迭代器 |
| values() | 返回数组 “元素” 的迭代器 |
| entries() | 返回数组 “索引和“元素”对的迭代器 |
| 查找判断 | |
| indexOf() | 返回指定元素首次出现的索引,未找到返回 -1 |
| lastIndexOf() | 返回指定元素最后出现的索引,未找到返回 -1 |
| includes() | 判断数组是否包含指定元素,返回布尔值 |
| find() | 返回首个满足条件的元素,未找到返回 undefined |
| findIndex() | 返回首个满足条件的元素索引,未找到返回 -1 |
| findLast() | 返回最后一个满足条件的元素,未找到返回 undefined |
| findLastIndex() | 返回最后一个满足条件的元素索引,未找到返回 -1 |
| every() | 判断是否所有元素都满足条件,返回布尔值 |
| some() | 判断是否有元素满足条件,返回布尔值 |
| 其他 | |
| join() | 将数组元素连接成字符串,返回字符串 |
| slice() | 提取数组的指定部分,返回新数组 |
| concat() | 合并多个数组或值,返回新数组 |
| at() | 返回指定索引处的元素,支持负索引 |
| fill() | 用指定值填充数组的指定范围,修改原数组 |
| copyWithin() | 复制数组的一部分到另一位置,修改原数组 |
| flat() | 展平嵌套数组到指定深度,返回新数组 |
| flatMap() | 对每个元素应用函数并展平结果,返回新数组 |
| 通用 | |
| toString() | 返回数组的字符串表示 |
| toLocaleString() | 返回数组的本地化字符串表示 |
| valueOf() | 返回数组对象的原始值(数组本身) |
提示: 在 JavaScript 开发中,数组同样极其重要。因此学完这一章之后,建议小伙伴们把表中这些字符串方法都过一遍。继续相信哥,这个对你帮助是非常大的。
