JavaScript: JavaScript 数组基础
数组就像一排编号的抽屉——每个抽屉有个编号(索引),里面放着东西(数据)。你可以按编号取东西、换东西、往后面加新东西。日常开发中,数组是你用得最多的数据结构。
1. 什么是数组
数组是有序的数据集合,可以存放任意类型的数据:
HTML
<script>
let arr = [1, 'hello', true, null, undefined];
</script>
一个数组里可以混合不同类型,但实际开发中通常放同类型的数据,方便统一处理。
▶ 示例
JAVASCRIPT
// 本节代码示例
const message = "你好,世界!";
console.log(message);
这是最简单的示例,后续章节会详细解释。## 2. 创建数组
两种方式:
HTML
<script>
// 方式1:字面量(推荐,简洁直观)
let fruits = ['苹果', '香蕉', '橘子'];
// 方式2:Array 构造函数
let nums = new Array(1, 2, 3);
let empty = new Array(5); // 创建长度为5的空数组,不是 [5]!
</script>
⚠️ 注意:
new Array(5) 创建的是一个长度为 5 的空数组,不是包含数字 5 的数组!这个坑踩过的人不少,所以日常用字面量 [] 就好。
3. 访问元素
数组索引从 0 开始,不是从 1。第一个元素是 [0],第二个是 [1],依此类推:
HTML
<script>
let fruits = ['苹果', '香蕉', '橘子'];
fruits[0]; // '苹果'
fruits[1]; // '香蕉'
fruits[2]; // '橘子'
</script>
访问不存在的索引不会报错,返回 undefined:
HTML
<script>
fruits[5]; // undefined
</script>
4. length 属性
length 返回数组的长度(元素个数):
HTML
<script>
let arr = [10, 20, 30];
arr.length; // 3
</script>
length 比 最大索引多 1,因为索引从 0 开始。最后一个元素的索引是 arr.length - 1。
5. 修改元素
直接通过索引赋值就能修改:
HTML
<script>
let fruits = ['苹果', '香蕉', '橘子'];
fruits[1] = '葡萄'; // 把'香蕉'改成'葡萄'
// ['苹果', '葡萄', '橘子']
</script>
也可以通过索引添加新元素(但不推荐,会产生空洞):
HTML
<script>
fruits[5] = '西瓜';
// ['苹果', '葡萄', '橘子', empty × 2, '西瓜']
</script>
▶ 示例:数组基本操作
HTML
<!DOCTYPE html>
<html>
<body>
<h2>数组基本操作</h2>
<div id="output"></div>
<script>
let fruits = ['苹果', '香蕉', '橘子', '葡萄', '西瓜'];
let html = '<strong>原始数组:</strong>' + fruits.join(', ') + '<br>';
html += '<strong>长度:</strong>' + fruits.length + '<br>';
html += '<strong>第一个:</strong>' + fruits[0] + '<br>';
html += '<strong>最后一个:</strong>' + fruits[fruits.length - 1] + '<br><br>';
fruits[1] = '芒果';
html += '<strong>修改索引1后:</strong>' + fruits.join(', ') + '<br>';
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
6. 基本方法
数组最常用的增删方法:
| 方法 | 作用 | 返回值 |
|---|---|---|
push() |
末尾添加元素 | 新长度 |
pop() |
末尾删除元素 | 被删的元素 |
unshift() |
开头添加元素 | 新长度 |
shift() |
开头删除元素 | 被删的元素 |
HTML
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>数组方法</title></head>
<body>
<pre id="output"></pre>
<script>
let arr = ['a', 'b', 'c'];
arr.push('d'); // ['a','b','c','d'] 返回 4
arr.pop(); // ['a','b','c'] 返回 'd'
arr.unshift('z'); // ['z','a','b','c'] 返回 4
arr.shift(); // ['a','b','c'] 返回 'z'
document.getElementById('output').textContent = JSON.stringify(arr);
</script>
</body>
</html>
💡 提示: 记忆技巧:
push/pop 操作尾部,unshift/shift 操作头部。p 开头的操作尾部,s 开头的操作头部。un 开头的加、不带的删。
▶ 示例:水果列表操作
HTML
<!DOCTYPE html>
<html>
<body>
<h2>水果列表管理</h2>
<input type="text" id="fruitInput" placeholder="输入水果名">
<button onclick="addFruit()">添加到末尾</button>
<button onclick="removeLast()">删除末尾</button>
<p id="output"></p>
<script>
let fruits = ['苹果', '香蕉', '橘子'];
function showFruits() {
let html = '<strong>当前水果列表:</strong><br>';
if (fruits.length === 0) {
html += '(空列表)';
} else {
for (let i = 0; i < fruits.length; i++) {
html += `[${i}] ${fruits[i]}<br>`;
}
}
html += `<br>共 ${fruits.length} 种水果`;
document.getElementById('output').innerHTML = html;
}
function addFruit() {
let name = document.getElementById('fruitInput').value.trim();
if (name) {
fruits.push(name);
document.getElementById('fruitInput').value = '';
showFruits();
}
}
function removeLast() {
if (fruits.length > 0) {
let removed = fruits.pop();
showFruits();
}
}
showFruits();
</script>
</body>
</html>
7. 检测数组:Array.isArray() vs typeof
typeof 对数组返回的是 "object",无法区分数组和普通对象:
HTML
<script>
let arr = [1, 2, 3];
typeof arr; // "object" ← 没用!
Array.isArray(arr); // true ← 正确方式
</script>
⚠️ 注意:
typeof 判断数组靠不住,始终用 Array.isArray()。
8. forEach 基本遍历
forEach 是遍历数组最常见的方法,比 for 循环更声明式:
HTML
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>forEach</title></head>
<body>
<pre id="output"></pre>
<script>
let fruits = ['苹果', '香蕉', '橘子'];
let result = '';
fruits.forEach(function(fruit, index) {
result += index + ' ' + fruit + '\n';
});
document.getElementById('output').textContent = result;
</script>
</body>
</html>
用箭头函数更简洁:
HTML
<script>
fruits.forEach((fruit, index) => {
console.log(index, fruit);
});
</script>
▶ 示例:forEach 遍历展示
HTML
<!DOCTYPE html>
<html>
<body>
<h2>forEach 遍历数组</h2>
<div id="output"></div>
<script>
let students = [
{ name: '小明', score: 92 },
{ name: '小红', score: 85 },
{ name: '小刚', score: 78 },
{ name: '小丽', score: 96 }
];
let html = '<table border="1" cellpadding="8" style="border-collapse:collapse">';
html += '<tr><th>序号</th><th>姓名</th><th>分数</th><th>等级</th></tr>';
students.forEach((s, i) => {
let grade = s.score >= 90 ? '优秀' : s.score >= 80 ? '良好' : '及格';
let color = s.score >= 90 ? 'green' : s.score >= 80 ? 'blue' : 'orange';
html += `<tr>
<td>${i + 1}</td>
<td>${s.name}</td>
<td>${s.score}</td>
<td style="color:${color}">${grade}</td>
</tr>`;
});
html += '</table>';
let total = 0;
students.forEach(s => total += s.score);
html += `<p>平均分:${(total / students.length).toFixed(1)}</p>`;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
⚠️ 注意: 高阶方法(
map、filter、reduce 等)功能更强大,下一课专门讲。
❓ 常见问题
Q
push 和 unshift 的返回值是什么?A 都返回数组的新长度,不是修改后的数组。很多人以为返回数组本身,结果
let arr = [1].push(2) 得到的是 2(长度),不是 [1, 2]。Q
forEach 里能用 break 跳出循环吗?A 不能。
forEach 没有 break 机制,想提前中断遍历请用传统 for 循环或 for...of + break。Q 数组越界访问会报错吗?
A 不会。
arr[100] 在越界时返回 undefined,不会抛异常。但这可能掩盖 bug,访问前最好检查索引范围。📖 小节
- 数组用字面量
[]创建,避免用new Array()(容易踩坑) - 索引从 0 开始,最后一个元素索引是
length - 1 push/pop操作尾部,unshift/shift操作头部- 检测数组用
Array.isArray(),typeof返回"object"靠不住 forEach遍历数组比for更声明式,但不能用break中断
📝 作业
- 创建一个数组存放 5 个城市名,用
forEach在页面上列出每个城市的序号和名称 - 写一个"待办清单":可以输入任务添加到末尾,点击"完成"删除末尾任务,实时显示列表
- 写一个程序:让用户输入 5 个数字存入数组,计算并显示它们的总和和平均值