1. 什么是数组?

大白话解释: 想象你有一个书架,数组就是这个书架,书架上每本书就是数组里的元素。数组能按顺序存放多个值,每个值都有编号(索引),从0开始。

// 一个简单的数字数组
let scores: number[] = [98, 76, 85, 90];

// 一个字符串数组
let fruits: string[] = [“苹果”, “香蕉”, “橙子”];

💡 数组就像火车车厢,每节车厢都有编号,可以装不同的东西。

2. 创建数组的两种方式

方式一:字面量创建(推荐)

// 创建一个数字数组
let numbers: number[] = [1, 2, 3, 4, 5];

// 创建一个混合类型数组(用any类型)
let mixedArray: any[] = [1, “苹果”, true, {name: “小明”}];

方式二:使用Array构造函数

// 创建一个空数组
let emptyArray: number[] = new Array();

// 创建指定长度的数组
let arrayWithSize: string[] = new Array(5); // 长度为5的空数组

// 创建带初始值的数组
let names: string[] = new Array(“张三”, “李四”, “王五”);

⚠️ 注意:在TypeScript中,最好指定数组类型(如number[]),这样编译器能帮我们检查类型错误。

3. 访问和修改数组元素

数组就像一排储物柜,每个柜子都有编号(索引)。索引从0开始,第一个元素索引是0,第二个是1,以此类推。

访问元素

let fruits: string[] = [“苹果”, “香蕉”, “橙子”];

console.log(fruits[0]); // 输出: “苹果”
console.log(fruits[2]); // 输出: “橙子”

修改元素

let fruits: string[] = [“苹果”, “香蕉”, “橙子”];

// 修改第二个元素
fruits[1] = “葡萄”;

console.log(fruits); // 输出: [“苹果”, “葡萄”, “橙子”]

💡 如果访问不存在的索引(比如fruits[5]),会得到undefined,不会报错。

4. 常用数组方法大全

数组有很多内置方法,就像瑞士军刀一样多功能:

方法名 作用 示例
push() 在数组末尾添加元素 fruits.push(“西瓜”); // 添加到最后
pop() 移除最后一个元素 fruits.pop(); // 移除最后一个
shift() 移除第一个元素 fruits.shift(); // 移除第一个
unshift() 在开头添加元素 fruits.unshift(“柠檬”); // 添加到开头
concat() 合并两个数组 let allFruits = fruits.concat([“桃子”, “梨”]);
slice() 截取部分数组 let someFruits = fruits.slice(1, 3); // 索引1到3
splice() 添加/删除元素 fruits.splice(1, 1, “芒果”); // 从索引1开始删1个,添加芒果
indexOf() 查找元素索引 let index = fruits.indexOf(“香蕉”); // 返回索引或-1
includes() 检查是否包含元素 let hasApple = fruits.includes(“苹果”); // true或false
forEach() 遍历数组 fruits.forEach(fruit => console.log(fruit));
map() 创建新数组 let lengths = fruits.map(fruit => fruit.length);
filter() 过滤数组元素 let longFruits = fruits.filter(fruit => fruit.length > 2);
find() 查找第一个符合条件的元素 let result = fruits.find(fruit => fruit.startsWith(“苹”));

⚠️ 注意:push/pop操作数组尾部(速度快),shift/unshift操作数组头部(速度慢)。

5. 多维数组(数组中的数组)

就像书架上有多个格子,每个格子又是一个小书架。最常见的是二维数组(表格)。

// 创建一个二维数组表示井字棋棋盘
let board: string[][] = [
  [“X”, “O”, “X”],
  [“O”, “X”, “O”],
  [“O”, “X”, “O”]
];

// 访问第二行第三列的元素
console.log(board[1][2]); // 输出: “O”

💡 三维数组(比如立方体)也是类似的,只是多一层:let cube: number[][][] = [[[1,2],[3,4]], [[5,6],[7,8]]];

6. 元组(Tuple) – 特殊数组

元组是固定长度、固定类型的数组。就像表格中的一行,每列数据类型是确定的。

// 定义一个元组类型
let person: [string, number, boolean];

// 正确赋值
person = [“张三”, 28, true];

// 错误赋值(类型或数量不对)
// person = [30, “张三”, true]; // 报错!
// person = [“李四”, 25]; // 报错!缺少元素

⚠️ 注意:元组在React的useState钩子中很常见:const [count, setCount] = useState(0);

7. 数组解构赋值

解构就像拆快递盒,把数组里的元素拆出来放到单独的变量里。

let fruits: string[] = [“苹果”, “香蕉”, “橙子”];

// 传统方式
// let first = fruits[0];
// let second = fruits[1];

// 解构方式(更简洁)
let [first, second, third] = fruits;

console.log(first); // “苹果”
console.log(second); // “香蕉”
console.log(third); // “橙子”

💡 技巧:可以用逗号跳过不需要的元素:let [a, , c] = fruits; // a=”苹果”, c=”橙子”

8. 只读数组(Readonly Array)

有时候我们不想让数组被修改,就像博物馆的展品只能看不能摸。

// 创建只读数组
const readOnlyFruits: ReadonlyArray<string> = [“苹果”, “香蕉”, “橙子”];

// 以下操作都会报错:
// readOnlyFruits.push(“葡萄”); // 错误!
// readOnlyFruits[0] = “梨”; // 错误!

// 只能读取:
console.log(readOnlyFruits[1]); // “香蕉”

💡 使用场景:函数参数传递数组时,如果不希望函数内部修改数组,可以用ReadonlyArray。

📚 数组知识点总结

  • 数组是有序的元素集合,每个元素有索引(从0开始)
  • 创建数组用[]new Array(),建议指定类型
  • 访问元素用数组名[索引],修改同理
  • 掌握push/pop/shift/unshift等核心方法
  • 使用map/filter/find等高级方法处理数组
  • 多维数组是”数组的数组”,用于表格等结构
  • 元组是固定长度和类型的特殊数组
  • 解构赋值可以快速提取数组元素
  • 只读数组(ReadonlyArray)保护数组不被修改