1. 数组到底是个啥?
数组是一种数据结构,用于存储固定大小的同类型元素序列,按连续内存位置排列,可通过索引快速访问元素。
想象一下,你家冰箱里有一格格小抽屉:第一格放鸡蛋、第二格放牛奶、第三格放可乐……
这每一格就是一个“存储位置”,而整个冰箱就是 数组。
在 JavaScript 里,数组就是一个 按顺序存放数据的容器,每个数据都可以通过“编号”(索引)取出来。
👉 举个代码例子:
// 创建一个数组
const fridge = ["鸡蛋", "牛奶", "可乐"];
// 拿第一格的东西(注意:数组从 0 开始数)
console.log(fridge[0]); // "鸡蛋"
// 拿第三格的东西
console.log(fridge[2]); // "可乐"
是不是和家里的冰箱一样?打开看第几格就能拿出来。
2. 数组怎么创建?
① 用字面量(最常见)
const arr = [1, 2, 3];
② 用构造函数(不常用,但要知道)
const arr = new Array(1, 2, 3);
⚠️ 注意:
const arr = new Array(3);
console.log(arr); // [ <3 empty items> ]
这可不是 [3]
,而是一个长度为 3 的“空冰箱”。所以开发中推荐 用字面量 []
,更直观。
3. 数组的索引和长度
数组的每个元素都有一个编号(索引 index),从 0 开始。
数组还会自动记录自己有多长(length)。
const fruits = ["苹果", "香蕉", "橙子"];
console.log(fruits[0]); // 苹果
console.log(fruits[1]); // 香蕉
console.log(fruits[2]); // 橙子
// 长度
console.log(fruits.length); // 3
💡 小坑:如果你访问不存在的索引呢?
console.log(fruits[10]); // undefined (显示未定义,空的,啥也没有)
4. 遍历数组:就像点名
想象你是班主任,点名的时候从第一号到最后一号,挨个叫名字。数组遍历就是这么个事。
-
for 循环(老牌方式)
for (let i = 0; i < students.length; i++) { console.log("点名:", students[i]); }
- 特点:通过索引访问,适合需要索引的场景,性能较高。
-
for...of 循环(ES6 的新方式,更优雅)
for (const student of students) { console.log("点名:", student); }
- 特点:直接迭代数组元素,代码简洁,无需手动管理索引。
-
forEach 方法(内置方法)
students.forEach((student, index) => { console.log(`点名[${index}]:`, student); });
- 特点:函数式编程风格,内置方法,适合简单遍历,回调函数可访问元素、索引和数组本身。
-
map 方法
students.map((student, index) => { console.log("点名:", student); return student; // map 要求返回值 });
- 特点:用于创建新数组,遍历同时可对元素进行转换,适合需要生成新数据的场景。
-
for...in 循环(不推荐用于数组)
for (const index in students) { console.log("点名:", students[index]); }
- 特点:主要用于对象属性枚举,遍历数组时可能包含非索引属性,性能较低,不推荐。
-
entries() 方法结合 for...of
for (const [index, student] of students.entries()) { console.log(`点名[${index}]:`, student); }
- 特点:同时获取索引和元素,解构赋值使代码更优雅。
-
filter 方法(间接遍历)
students.filter(student => { console.log("点名:", student); return true; // filter 要求返回布尔值 });
- 特点:用于筛选元素并返回新数组,遍历为副作用,适合筛选场景。
-
reduce 方法(间接遍历)
students.reduce((_, student) => { console.log("点名:", student); return null; // reduce 要求返回值 }, null);
- 特点:用于累积计算,遍历为副作用,适合需要聚合操作的场景。
5. 修改数组:随手换个食材
数组里的东西不是固定的,你可以随时换掉。
const fridge = ["鸡蛋", "牛奶", "可乐"];
// 把“牛奶”换成“豆浆”
fridge[1] = "豆浆";
console.log(fridge); // ["鸡蛋", "豆浆", "可乐"]
甚至还能直接往后加新的:
fridge[3] = "雪糕";
console.log(fridge); // ["鸡蛋", "豆浆", "可乐", "雪糕"]
6.数组与对象的区别
- 定义不同
- 数组(Array):一种有序的数据集合,常用来存放一组“列表式”的数据。
- 对象(Object):一种无序的键值对(key-value)集合,常用来存放具有属性的数据。
就像:
- 数组更像“排队买奶茶的人”——有先来后到的顺序,按编号找人。
- 对象更像“身份证档案”——你要通过身份证号(key)才能查到对应的人。
- 访问方式不同
// 数组:通过下标(index)访问
const arr = ["苹果", "香蕉", "橘子"];
console.log(arr[0]); // 苹果
console.log(arr[2]); // 橘子
// 对象:通过键(key)访问
const obj = { name: "小明", age: 18 };
console.log(obj.name); // 小明
console.log(obj["age"]); // 18
- 适用场景不同
-
数组
- 数据有顺序
- 适合批量操作:遍历、排序、筛选
- 比如:成绩单
[98, 85, 73]
,购物车[商品1, 商品2, 商品3]
-
对象
- 数据无顺序,靠键来标识
- 适合描述一个实体或一组属性
- 比如:学生
{ name: "小明", age: 18, score: 98 }
- 内置方法不同
-
数组:有很多自带方法,方便操作
arr.push("葡萄"); // 添加 arr.pop(); // 删除最后一个 arr.map(x => x+"好吃"); // 遍历加工
-
对象:没有像数组那样的“遍历加工”方法,但可以用
Object.keys(obj); // 获取所有 key Object.values(obj); // 获取所有 value Object.entries(obj); // 转成二维数组
- 底层表现不同
- 数组的键本质上也是对象的键,只是默认用数字下标,而且它有
length
属性。 - 对象的键一般是字符串(或 symbol)。
const arr = ["a", "b"];
arr["foo"] = "bar";
console.log(arr); // ["a", "b", foo: "bar"]
console.log(arr.length); // 2 (不会数上foo)
到此我们对数组就有一个大概了解了。
我们来总结一下,数组 = 前端世界里最常用的“多功能收纳箱”。
下一篇,我们就要开始玩转 数组的增删改神器(push
、pop
、splice
等),看看怎么优雅地往收纳箱里塞东西、拿东西。🚀
评论区