主题
1-11数组综合案例
本页对应 第一章JavaScript基础,共 5 段视频,约 52 分钟。
学习目标
- 能够使用“声明空字符串 → 循环拼接标签字符串 → 插入指定容器”的步骤,用 JavaScript 动态生成多个 DOM 元素。
- 能够通过循环连续弹出 4 次输入框,将用户输入转换为数字并按顺序存入数组。
- 能够根据数组数据渲染柱形图,正确设置每个柱子的高度、提示文本、数值文本和季度标签。
- 能够使用数组
sort()实现升序与降序排序,并说明其会修改原数组,且能据此获取数组最大值和最小值。 - 能够描述选择排序的基本步骤,并使用双重循环与变量交换手写完成数组排序。
知识点
数组是什么:先理解“一个变量装多个值”
为什么需要:保存一个同学姓名可以用一个变量,保存全班姓名再用一个个变量就很麻烦。数组的作用就是“在单个变量名下存储多个数据”,它属于引用数据类型。
怎么想:把数组看成一排有编号的格子,格子按顺序存放数据,每个格子叫数组单元,也叫数组元素。
怎么做:用 [] 表示数组,元素之间用英文逗号分隔。
易错点:数组元素可以是任意数据类型;逗号必须是英文逗号;数组按顺序存储,编号从 0 开始。
定义数组:空数组与非空数组
为什么需要:有时先准备空数组,等用户输入或循环时再追加;有时一开始就有数据。
怎么想:let classes = [] 是空数组;let classes = ['小明', ...] 是非空数组。
怎么做:
html
<script>
// 1. 语法,使用 [] 来定义一个空数组
// 定义一个空数组,然后赋值给变量 classes
// let classes = []
// 2. 定义非空数组
let classes = ['小明', '小刚', '小红', '小丽', '小米']
</script>易错点:不要写成中文逗号;数组里每一项称为数组单元/元素;空数组不是没有变量,而是变量里装了一个空集合。
访问数组和数组索引:用编号取数据
为什么需要:存数据不是目的,关键是要能随时访问某个数据。
怎么想:JavaScript 给每个数组单元编号,称为索引值或下标,从 0 开始。图中【小明】索引为 0,【小红】索引为 2。
怎么做:语法是 数组名[下标]。

html
<script>
// 数组: 可以单个变量下存储多个数据
// 1. 声明数组
let names = ['小明', '小刚', '小红', '小丽', '小米']
// let names = ['小明', '小刚', true, '小丽', 1]
console.log(names)
// 1.1 数组是按照顺序来存储的,每个数据都有自己的编号
// 1.2 编号是从0开始的, 0 1 2 3... 也称为 索引 或者 下标
// 1.3 数组里面可以存放任意的数据类型
// 2. 数组取值 数组名[下标]
console.log(names[0]) // '小明'
console.log(names[1]) // '小刚'
console.log(names[2]) // '小红'
console.log(names[3]) // '小丽'
console.log(names[4]) // '小米'
</script>易错点:第一个元素是 [0],不是 [1];访问不存在的索引返回 undefined;数组单元可以是字符串、数字、布尔值等混合类型。
html
<script>
// 6. 数组单值类型可以是任意数据类型
// a) 数组单元值的类型为字符类型
let list = ['HTML', 'CSS', 'JavaScript']
// b) 数组单元值的类型为数值类型
let scores = [78, 84, 70, 62, 75]
// c) 混合多种类型
let mixin = [true, 1, false, 'hello']
</script>遍历数组:用循环访问每个元素
为什么需要:数组元素多时,不可能一个个 console.log。遍历就是把数组中每个数据都访问到。
怎么想:索引从 0 开始,循环变量 i 也从 0 开始;结束条件用 arr.length,不要写死数字。
怎么做:
html
<script>
let arr = ['迪丽热巴', '古力娜扎', '佟丽丫丫', '玛尔扎哈', '哈尼克孜']
// console.log(arr[0])
// console.log(arr[1])
// console.log(arr[2])
// console.log(arr[3])
// 遍历数组: 把数组里面的数据每个都会访问到
// for (let i = 0; i < 4; i++) {
// // console.log(i) 数组名[索引号]
// console.log(arr[i])
// }
// 1. 数组的长度 数组.length
// console.log(arr.length) // 4
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
// 2. 数组里面的数据也称为 数组元素
</script>易错点:循环条件写 i <= arr.length 会多访问一次,得到 undefined;数组长度是 arr.length,不是 arr.length()。转写稿中的手风琴案例也是先准备图片地址数组,再循环拼接字符串生成多个标签,说明遍历数组常和“批量生成结构”一起用。
查询和修改数组:查不到是 undefined,改不存在会增长度
为什么需要:实际使用中既要读取某个元素,也要改某个元素。
怎么想:查询用 数组[索引];修改用 数组[索引] = 新值。
怎么做:

html
<script>
// 1. 查询数组元素
let arr = ['迪丽热巴', '古丽扎娜']
console.log(arr[0]) // '迪丽热巴'
console.log(arr[1]) // '古丽扎娜'
console.log(arr[2]) // undefined
// 2. 修改数组元素 数组[索引] = 新值
arr[1] = '佟丽丫丫'
// console.log(arr)
arr[3] = '古丽扎娜' // 如果索引号不存在,则是增加数组元素 (不提倡)
console.log(arr)
console.log(arr.length) // 4 修改了数组长度
</script>易错点:查询不到返回 undefined;给不存在的索引赋值会新增元素并改变长度,初学阶段应尽量避免。
新增元素:push 末尾加,unshift 开头加
为什么需要:用户输入、循环生成数据时,经常要往数组里追加元素。
怎么想:末尾追加用 push,开头追加用 unshift;它们都会修改原数组。
怎么做:

javascript
// 数组新增元素
// 1. 可以向数组的末尾新增1个或者多个数组元素 数组.push(元素1...元素n)
let arr = ['迪丽热巴']
// console.log(arr.push('佟丽丫丫')) // 返回的是新数组的长度 2
// arr.push('佟丽丫丫', '古丽扎娜')
// console.log(arr) // 修改原数组
// 2. 可以向数组的开头增加1个或者多个数组元素 数组.unshift(元素1,...元素n)
// console.log(arr.unshift('佟丽丫丫')) // 返回的是新数组的长度 2
arr.unshift('佟丽丫丫', '古丽扎娜')
console.log(arr) // 修改原数组易错点:push/unshift 返回的是新长度,不是新数组;它们修改原数组。转写稿柱形图案例中,用户输入四次后把数据依次 push 进数组,就是为了后面按顺序渲染柱子。
删除元素:pop 删末尾,shift 删开头
为什么需要:数组元素需要动态减少。
怎么想:删最后一个用 pop(),删第一个用 shift(),都修改原数组。
怎么做:

javascript
<script>
// 删除元素
// 1. 删除数组中的最后一个元素 数组.pop() 修改原数组
let arr = ['red', 'green']
// arr.pop()
// console.log(arr.pop()) // 返回的是被删除的元素
// console.log(arr)
// 2. 删除数组中的第一个元素 数组.shift() 修改原数组的
arr.shift()
// console.log(arr.shift()) // 返回的是被删除的元素
console.log(arr)
</script>易错点:pop/shift 返回被删除的元素,不是数组长度;空数组删除得到 undefined。
splice方法:管中间的增加和删除
为什么需要:push/pop/unshift/shift 只管开头和末尾,中间位置要用 splice。
怎么想:splice(start, deleteCount, item1, item2...),start 从 0 计数;省略 deleteCount 表示删到最后;新增时 deleteCount 写 0。
怎么做:
javascript
<script>
// splice 删除和增加数组元素
let arr = ['迪丽热巴', '古丽娜扎', '佟丽丫丫', '玛尔扎哈']
// 1. splice 删除 数组.splice(起始位置, 删除几个)
// arr.splice(1, 1) // 记住起始位置是索引号,从0 开始数
// arr.splice(1) // 如果第二个参数(删除几个)省略了,则默认删除到最后
// console.log(arr)
// 2. splice 增加 数组.splice(起始位置, 删除几个, 新增元素1,...新增元素n)
arr.splice(1, 0, '刘德华', 'pink')
// 2.1 注意如果是新增,则起始位置是目标位置的索引号, 删除几个(第二个参数)不能省略我们写为 0, 后面写新增的元素
console.log(arr)
// 3. splice 不是替换pop shift unshift push. arr.splice(0, 1)
// 开头结尾找前面 pop shift unshift push
// splice管中间
</script>易错点:start 是索引不是“第几个”;新增时第二个参数要写 0;splice 修改原数组,不要和 slice 混淆。转写稿拓展中提到 sort 排序会修改原数组,升序常写 return a - b,降序写 return b - a,这是后续数组操作中同样要注意“方法是否修改原数组”的思路。
手风琴效果:先看需求

为什么需要:页面里有 7 个结构几乎一样的 div>img,手写 7 次既重复又容易改漏。怎么想:把图片地址放进数组,用循环生成标签;手风琴的展开效果本身由 CSS :hover 和 transition 完成,JS 只负责“批量渲染结构”。怎么做:先注释静态 HTML,再按“空字符串 → 循环拼接 → 放入容器”三步走。易错点:空字符串必须写成 '';遍历数组从 0 开始;不要假设图片名一定是 1.jpg,应从数组取地址。
字符串拼接三步法
为什么需要:要生成多个相似标签,不能一条条手写。怎么想:它和累加和类似,str += ... 就是不断把新标签追加到字符串里。怎么做:① let str = '';② 循环里 str += 模板字符串;③ 用 document.write 把 str 放进 .box。转写稿中的调试过程是:先 console.log(arr[i]) 确认拿到图片地址,再拼接;拼接完 console.log(str) 看到 7 个 div,最后才渲染。易错点:模板字符串里取数组要用 \${arr[i]};document.write 前要确认静态结构已注释,避免页面重复出现两套卡片。
手风琴完整代码
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box {
display: flex;
overflow: hidden;
width: 1120px;
height: 260px;
margin: 50px auto;
}
.box>div {
width: 120px;
border: 1px solid #fff;
transition: all 0.5s;
}
.box>div:hover {
width: 400px;
}
</style>
</head>
<body>
<script>
let arr = [
'./images/1.jpg',
'./images/2.jpg',
'./images/3.jpg',
'./images/4.jpg',
'./images/5.jpg',
'./images/6.jpg',
'./images/7.jpg',
]
// 1. 声明一个空的字符串变量 str
let str = ''
// 2. 利用for循环拼接字符串 +=
for (let i = 0; i < arr.length; i++) {
str += `
<div><img src="${arr[i]}" alt=""></div>
`
}
console.log(str)
// 3. 把拼接的字符串放入 box盒子里面
document.write(`
<div class="box">
${str}
</div>
`)
</script>
</body>
</html>柱形图:先收集 4 个季度数据

为什么需要:柱子的高度要由用户输入决定,所以必须先保存 4 次输入。怎么想:不要写 4 个 prompt,用循环弹 4 次;输入值要按顺序保存,push 最合适。怎么做:声明空数组 arr;for (let i = 1; i <= 4; i++),用模板字符串提示“第 i 季度”;let num = +prompt(...) 转成数字;arr.push(num)。转写稿中先 console.log(arr) 验证数组里是否是 4 个数字。易错点:prompt 返回字符串,不转数字会影响高度计算;循环变量从 1 开始时,条件要写 <= 4;存数据用 push,不要用索引乱放。
渲染柱子:复用“三步法”
为什么需要:4 个柱子结构相似,只有高度、季度、数值不同。怎么想:仍用空字符串拼接,循环数组生成 4 个 div。怎么做:height:\${arr[i]}px;title="第\${i + 1}季度-\${arr[i]}万";span 显示 \${arr[i]}万;h4 显示第 \${i + 1} 季度;最后 document.write 包上 .box。易错点:数组索引从 0 开始,所以季度要 i + 1;高度别漏 px;title、span 中的“万”要和需求一致;先 console.log(str) 看 4 个柱子是否正确再渲染。
柱形图完整代码
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* { margin: 0; padding: 0; }
body { background-color: #0c143d; }
.box {
display: flex;
justify-content: space-around;
align-items: flex-end;
width: 800px;
min-height: 300px;
border-left: 1px solid #4b578f;
border-bottom: 1px solid #4b578f;
margin: 0 auto;
padding-top: 50px;
text-align: center;
color: #9799ab;
}
.box>div {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 40px;
height: 0;
background: linear-gradient(#3c99ff, #4489d0, #2283e4);
cursor: pointer;
border-radius: 8px 8px 0 0;
transition: all .2s;
}
.box>div:hover { animation: bg .5s alternate infinite; }
@keyframes bg {
to {
box-shadow: 0 5px 29px rgb(53 111 226 / 88%);
background: linear-gradient(#3c99ff, #68aff6, #2283e4);
}
}
.box>div::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 2px;
height: 10px;
background-color: #4b578f;
transform: translate(-50%, 100%);
}
.box div span { width: 60px; margin: -30px 0 -5px -6px; }
.box div h4 { width: 70px; margin: 0 0 -35px -10px; }
.title { margin-top: 50px; text-align: center; color: #9799ab; }
</style>
</head>
<body>
<h3 class="title">2099年季度销售数额(单位万)</h3>
<script>
// 功能1:用户输入4次,并且把数据存放到数组里面
let arr = []
for (let i = 1; i <= 4; i++) {
let num = +prompt(`请您输入第${i}季度的销售额`)
arr.push(num)
}
console.log(arr)
// 功能2:根据数组生成柱形图
let str = ''
for (let i = 0; i < arr.length; i++) {
str += `
<div style="height: ${arr[i]}px;" title="第${i + 1}季度-${arr[i]}万">
<span>${arr[i]}万</span>
<h4>第${i + 1}季度</h4>
</div>
`
}
console.log(str)
document.write(`
<div class="box">
${str}
</div>
`)
</script>
</body>
</html>小结:两个案例的共同套路
两个案例都在练“数据驱动渲染”:先准备数组,再用循环拼接字符串,最后放入容器。手风琴的重点是图片地址来自数组;柱形图的重点是输入值要转数字、高度和季度文案要动态替换。调试时不要一上来就写完整页面,先打印数组,再打印拼接后的 str,确认结构无误后再 document.write,这样排错最快。
课件图示








代码示例
示例一:数组的声明、访问、遍历与增删改查
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组基本使用</title>
</head>
<body>
<script>
// 1. 声明数组
let names = ['小明', '小刚', '小红', '小丽', '小米']
// let names = ['小明', '小刚', true, '小丽', 1]
console.log(names)
// 1.1 数组是按照顺序来存储的,每个数据都有自己的编号
// 1.2 编号是从0开始的, 0 1 2 3... 也称为 索引 或者 下标
// 1.3 数组里面可以存放任意的数据类型
// 2. 数组取值 数组名[下标]
console.log(names[0]) // '小明'
console.log(names[1]) // '小刚'
console.log(names[2]) // '小红'
console.log(names[3]) // '小丽'
console.log(names[4]) // '小米'
</script>
<script>
// 6. 数组单值类型可以是任意数据类型
// a) 数组单元值的类型为字符类型
let list = ['HTML', 'CSS', 'JavaScript']
// b) 数组单元值的类型为数值类型
let scores = [78, 84, 70, 62, 75]
// c) 混合多种类型
let mixin = [true, 1, false, 'hello']
console.log(list, scores, mixin)
</script>
<script>
// 遍历数组: 把数组里面的数据每个都会访问到
let arr = ['迪丽热巴', '古丽娜扎', '佟丽丫丫', '玛尔扎哈', '哈尼克孜']
// 1. 数组的长度 数组.length
console.log(arr.length)
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
// 2. 数组里面的数据也称为 数组元素
</script>
<script>
// 1. 查询数组元素
let arr = ['迪丽热巴', '古丽扎娜']
console.log(arr[0]) // '迪丽热巴'
console.log(arr[1]) // '古丽扎娜'
console.log(arr[2]) // undefined
// 2. 修改数组元素 数组[索引] = 新值
arr[1] = '佟丽丫丫'
arr[3] = '古丽扎娜' // 如果索引号不存在,则是增加数组元素 (不提倡)
console.log(arr)
console.log(arr.length) // 4 修改了数组长度
</script>
<script>
// 数组新增元素
// 1. 可以向数组的末尾新增1个或者多个数组元素 数组.push(元素1...元素n)
let arr = ['迪丽热巴']
// console.log(arr.push('佟丽丫丫')) // 返回的是新数组的长度 2
// arr.push('佟丽丫丫', '古丽扎娜')
// console.log(arr) // 修改原数组
// 2. 可以向数组的开头增加1个或者多个数组元素 数组.unshift(元素1,...元素n)
// console.log(arr.unshift('佟丽丫丫')) // 返回的是新数组的长度 2
arr.unshift('佟丽丫丫', '古丽扎娜')
console.log(arr) // 修改原数组
</script>
<script>
// 删除元素
// 1. 删除数组中的最后一个元素 数组.pop() 修改原数组
let arr = ['red', 'green']
// arr.pop()
// console.log(arr.pop()) // 返回的是被删除的元素
// console.log(arr)
// 2. 删除数组中的第一个元素 数组.shift() 修改原数组的
arr.shift()
// console.log(arr.shift()) // 返回的是被删除的元素
console.log(arr)
</script>
<script>
// splice 删除和增加数组元素
let arr = ['迪丽热巴', '古丽娜扎', '佟丽丫丫', '玛尔扎哈']
// 1. splice 删除 数组.splice(起始位置, 删除几个)
// arr.splice(1, 1) // 记住起始位置是索引号,从0 开始数
// arr.splice(1) // 如果第二个参数(删除几个)省略了,则默认删除到最后
// console.log(arr)
// 2. splice 增加 数组.splice(起始位置, 删除几个, 新增元素1,...新增元素n)
arr.splice(1, 0, '刘德华', 'pink')
// 2.1 注意如果是新增,则起始位置是目标位置的索引号, 删除几个(第二个参数)不能省略我们写为 0, 后面写新增的元素
console.log(arr)
// 3. splice 不是替换pop shift unshift push. arr.splice(0, 1)
// 开头结尾找前面 pop shift unshift push
// splice管中间
</script>
</body>
</html>关键行与易错点
let names = ['小明', ...]:数组用[]定义,单元之间必须用英文逗号分隔;数组单元可以是任意数据类型(字符、数值、布尔、混合)。names[0]:索引(下标)从 0 开始,不是 1,所以 5 个元素的最大索引是 4。console.log(arr[2])查不到时返回undefined,不是报错。arr[3] = '古丽扎娜':当索引号超出范围时会新增元素并改变 length,课上明确说不提倡这么用,新增请用push/unshift/splice。arr.push()/arr.unshift()返回的是新数组长度;arr.pop()/arr.shift()返回的是被删除的那个元素,且四者都修改原数组。arr.length用于遍历,写i < arr.length而不是写死数字,数组变了循环依然正确。arr.splice(1, 1):第二个参数是删除的个数,省略则从起始位置删到最后;做“新增”时第二个参数必须写0,否则会误删元素。- 多个
<script>里都用let arr不会冲突(各自独立作用域),若写在同一个<script>里重复let声明会报错。
示例二:综合案例——手风琴效果(循环拼接字符串渲染 7 个 div)
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box {
display: flex;
overflow: hidden;
width: 1120px;
height: 260px;
margin: 50px auto;
}
.box>div {
width: 120px;
border: 1px solid #fff;
transition: all 0.5s;
}
.box>div:hover {
width: 400px;
}
</style>
</head>
<body>
<!-- <div class="box">
<div><img src="./images/1.jpg" alt=""></div>
<div><img src="./images/2.jpg" alt=""></div>
<div><img src="./images/3.jpg" alt=""></div>
<div><img src="./images/4.jpg" alt=""></div>
<div><img src="./images/5.jpg" alt=""></div>
<div><img src="./images/6.jpg" alt=""></div>
<div><img src="./images/7.jpg" alt=""></div>
</div> -->
<script>
let arr = [
'./images/1.jpg',
'./images/2.jpg',
'./images/3.jpg',
'./images/4.jpg',
'./images/5.jpg',
'./images/6.jpg',
'./images/7.jpg',
]
// 1. 声明一个空的字符串变量 str
let str = ''
// 2. 利用for循环拼接字符串 +=
for (let i = 0; i < arr.length; i++) {
// console.log(arr[i])
str += `
<div><img src="${arr[i]}" alt=""></div>
`
}
console.log(str)
// 3. 把拼接的字符串放入 box盒子里面
document.write(`
<div class="box">
${str}
</div>
`)
</script>
</body>
</html>关键行与易错点
let str = '':必须初始化为空字符串,否则str += ...会拼出undefined...。for (let i = 0; i < arr.length; i++):数组遍历从 0 开始、用< length,别写成<=,否则会多拼一个undefined的图。str += `...`:核心是累加拼接(原理同累加和),每循环一次就往字符串里追加一个div。src="\${arr[i]}":图片地址必须从数组里取,不要用i+1之类去拼文件名——真实项目里图片名不一定按 1~7 排列,取数组元素才可靠。document.write(...)把str塞进.box里渲染;document.write要在页面加载(渲染)阶段执行才能正确插入,放到事件里会把整个文档覆盖掉。- 手风琴的展开/收起是纯 CSS 完成的:
.box>div宽 120px,:hover变 400px,配合transition: all 0.5s;JS 只负责生成结构。 - 图片路径
./images/1.jpg需自备素材,路径不对时盒子在但看不到图。
示例三:综合案例——根据输入数据渲染柱形图
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #0c143d;
}
.box {
display: flex;
justify-content: space-around;
align-items: flex-end;
width: 800px;
min-height: 300px;
border-left: 1px solid #4b578f;
border-bottom: 1px solid #4b578f;
margin: 0 auto;
padding-top: 50px;
text-align: center;
color: #9799ab;
}
.box>div {
position: relative;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 40px;
height: 0;
background: linear-gradient(#3c99ff, #4489d0, #2283e4);
cursor: pointer;
border-radius: 8px 8px 0 0;
transition: all .2s;
}
.box>div:hover {
animation: bg .5s alternate infinite;
}
@keyframes bg {
to {
box-shadow: 0 5px 29px rgb(53 111 226 / 88%);
background: linear-gradient(#3c99ff, #68aff6, #2283e4);
}
}
.box>div::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 2px;
height: 10px;
background-color: #4b578f;
transform: translate(-50%, 100%);
}
.box div span {
width: 60px;
margin: -30px 0 -5px -6px;
}
.box div h4 {
width: 70px;
margin: 0 0 -35px -10px;
}
.title {
margin-top: 50px;
text-align: center;
color: #9799ab;
}
</style>
</head>
<body>
<h3 class="title">2099年季度销售数额(单位万)</h3>
<!-- <div class="box">
<div style="height: 123px;" title="第1季度-123万">
<span>123万</span>
<h4>第1季度</h4>
</div>
<div style="height: 156px;" title="第2季度-156万">
<span>156万</span>
<h4>第2季度</h4>
</div>
<div style="height: 120px;" title="第3季度-120万">
<span>120万</span>
<h4>第3季度</h4>
</div>
<div style="height: 210px;" title="第4季度-210万">
<span>210万</span>
<h4>第4季度</h4>
</div>
</div> -->
<script>
// 功能1: 用户输入4次,并且把数据存放到数组里面
// 1.1 声明一个空的数组
let arr = []
// 1.2 利用循环的形式让用户输入4次,并且把数据追加给数组
for (let i = 1; i <= 4; i++) {
let num = +prompt(`请您输入第${i}季度的销售额`)
arr.push(num)
}
console.log(arr)
// 功能2:根据数组生成柱形图
// 2.1 声明一个空的字符串 str
let str = ''
// 2.2 利用循环拼接字符串,生成多个柱子
for (let i = 0; i < arr.length; i++) {
str += `
<div style="height: ${arr[i]}px;" title="第${i + 1}季度-${arr[i]}万">
<span>${arr[i]}万</span>
<h4>第${i + 1}季度</h4>
</div>
`
}
console.log(str)
// 2.3 把生成的柱子放到box盒子里面进行渲染
document.write(`
<div class="box">
${str}
</div>
`)
</script>
</body>
</html>关键行与易错点
let num = +prompt(...):prompt返回的是字符串,用一元+转成数字,否则后面拼height会出错('200' + 'px'反而没问题,但数组里存字符串不方便比较)。for (let i = 1; i <= 4; i++):这里从 1 开始、用<= 4,因为要在提示语里显示“第1季度…第4季度”;和遍历数组的i = 0; i < arr.length是两种不同场景,别混。arr.push(num):依次把 4 次输入追加到数组末尾,保持季度顺序。- 第二个循环
for (let i = 0; i < arr.length; i++)又从 0 开始,因为要取arr[i]。 style="height: \${arr[i]}px;":柱子高度由数据决定,数据越大柱子越高——这是整个案例的“活数据”关键行。title="第\${i + 1}季度-\${arr[i]}万"和<h4>第\${i + 1}季度</h4>:显示季度要用i + 1,直接写i会出现“第0季度”。let str = ''空字符串初始化 +str +=累加,最后document.write包一层.box输出;三步顺序不能乱。- 取消
prompt会返回null,+null得到0,柱子高度就是 0(不会报错,但显示异常)。
常见错误
- 遍历多出
undefined或空标签:现象是最后多访问一次数组、多拼一个空项 → 原因是写成i <= arr.length→ 修法统一用i < arr.length。 - 拼接完字符串但页面不显示:现象是控制台有 HTML,页面空白 → 原因是只做了
str += ...,没有放入容器或document.write→ 修法先打印str检查,再渲染到目标容器。 - 把
push/pop/shift/unshift的返回值当数组用:现象是arr = arr.push(x)后arr变成数字 → 原因是这些方法返回长度或被删除元素,不是原数组 → 修法单独调用方法,不要重新赋值给arr。 splice参数写错导致误删或替换:现象是新增元素时删掉了原数据,或省略第二参数删到末尾 → 原因是新增时deleteCount必须写0,省略会删除到末尾 → 修法新增用arr.splice(start, 0, ...items),删除用arr.splice(start, count)。sort()直接排序结果不符合数值大小:现象是出现100, 99, 78...这类顺序 → 原因是默认按字符串/字符比较 → 修法数值升序用arr.sort((a, b) => a - b),降序用(a, b) => b - a。- 渲染季度时显示“第0季度”:现象是序号从 0 开始 → 原因是直接用了数组索引
i作为展示序号 → 修法展示层用i + 1,索引用i。
练习
- 给定数组
['HTML', 'CSS', 'JS'],用for循环输出“索引-元素”,要求不能出现undefined。 - 对数组
['red', 'green']依次执行push、unshift、pop、shift、splice,记录每步后的数组和返回值。 - 根据图片地址数组,循环拼接 7 个
<div><img></div>,并渲染到.box容器中。 - 对成绩数组
[78, 84, 70, 62, 75]分别做数值升序、降序,并取出最高分和最低分。 - 用选择排序处理
[4, 2, 5, 1, 3],写出外层轮数、minIndex的记录方式,以及何时交换。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 综合案例-手风琴案例 | 13:02 |
| 2 | 综合案例-渲染柱形图弹出4次输入框 | 08:44 |
| 3 | 综合案例-渲染柱形图渲染柱子 | 09:08 |
| 4 | 拓展知识-数组sort排序 | 07:49 |
| 5 | 拓展了解-选择排序 | 13:24 |
小结
- 数组适合在单个变量下管理多个相关数据,索引从
0开始,length表示元素个数。 - 查询用
arr[i],越界查询得到undefined;越界赋值会扩长度,但不推荐依赖。 - 遍历数组优先用
i < arr.length;展示序号时通常用i + 1。 push/pop管尾部,unshift/shift管头部,splice管中间;这些方法都会修改原数组。- 批量渲染标签可固定为三步:空字符串 → 循环
+=拼接 → 放入容器渲染。 - 数值排序必须给
sort传比较函数,不能直接依赖默认排序。 - 选择排序要抓住三点:外层控制轮数、内层找最小值索引、本轮结束后再交换。
- 写数组代码时优先使用标准 API 和清晰命名,避免越界赋值、返回值误用等隐式行为。