Skip to content

1-10数组和数组操作(一) ​

本页对应 第一章JavaScript基础,共 5 段视频,约 45 分钟。

学习目标 ​

  • 能使用数组字面量声明数组,并说明数组元素的索引从 0 开始、可存放任意数据类型。
  • 能通过“数组名[索引]”查询指定元素,并解释查询不存在的索引时返回 undefined。
  • 能使用 for 循环结合 length 属性遍历数组,正确输出全部数组元素。
  • 能编写程序对数组元素求和、求平均值,并说明累加变量需初始化为 0。
  • 能编写程序求数组最大值,并说明以首元素初始化最大值、循环比较并更新的执行过程。
  • 能通过“数组名[索引] = 新值”修改数组元素,并说明使用不存在索引赋值会新增元素且改变数组长度。

知识点 ​

为什么需要循环嵌套 ​

为什么需要:地球一边自转一边公转,可以类比为“重复里面还有重复”。单层循环只能描述一维重复,比如打印 5 个星号;遇到“第 1 天记 5 个单词、第 2 天再记 5 个单词”这种二维重复,就需要外层控制大轮次、内层控制每轮的小轮次。

宇宙公转自转示意图

怎么想:先找“外层重复什么”,再找“每轮里面重复什么”。外层是第 n 天,内层是第几个单词。

怎么做:JavaScript 中任何一种循环语句都支持嵌套。基本语法如下:

javascript
for(初始化; 循环条件;变量计数) {
  for(初始化; 循环条件;变量计数){
    //  要重复执行的代码
  }
}

实际编写时,括号和分号应使用英文半角。示例:

js
// 1. 外面的循环 记录第n天 
for (let i = 1; i < 4; i++) {
    document.write(`第${i}天 <br>`)
    // 2. 里层的循环记录 几个单词
    for (let j = 1; j < 6; j++) {
        document.write(`记住第${j}个单词<br>`)
    }
}

易错点:记住“外层循环循环一次,里层循环循环全部”。换行 <br> 应写在内层循环结束之后、外层循环体之内,否则会变成每个单词后都换行。内外层变量不要同名,常用 i、j。

执行顺序:先外层一次,再内层一轮 ​

为什么需要:不理解执行顺序,容易把嵌套循环误认为内外层交替执行。

怎么想:像班长点名:第 1 天先把 5 个单词逐个记完,再进入第 2 天。转写稿里讲数组遍历时,先 log 打印循环变量 i,看到 0 1 2 3 才继续取值;这个“先打印循环变量验证边界”的调试方法可以迁移到嵌套循环:先打印 i 和 j,观察谁变化慢、谁变化快。

怎么做:可临时加日志:

javascript
for (let i = 1; i <= 2; i++) {
  console.log('外层 i =', i)
  for (let j = 1; j <= 3; j++) {
    console.log('  内层 j =', j)
  }
}

会看到 i=1 时 j 从 1 到 3,然后 i=2 时 j 再从 1 到 3。

易错点:内层循环变量每轮都会重新初始化;如果把本应属于外层的语句误放进内层,会重复执行多次。

三角型:内层上界依赖外层 ​

为什么需要:要打印“第 1 行 1 个星、第 2 行 2 个星……”,每行星号数量不同,单层固定次数循环表达不了。

怎么想:外层 i 控制行数,内层 j 控制每行打印几个星。因为第 i 行要打印 i 个,所以内层条件是 j <= i。

怎么做:

javascript
 // 外层打印几行
for (let i = 1; i <= 5; i++) {
    // 里层打印几个星星
    for (let j = 1; j <= i; j++) {
        document.write('★')
    }
    document.write('<br>')
}

直角三角形星号图案

易错点:内层不能写成 j <= 5,否则每行都是 5 个星;document.write('<br>') 必须放在内层循环外,否则星号会竖着排列。

九九乘法表:把星号换成算式 ​

为什么需要:乘法表是二维表格,行和列都在变化,正好用嵌套循环表达。

怎么想:外层 i 表示行,内层 j 表示列;第 i 行有 i 列,所以仍是 j <= i。只需把三角型中的 ★ 换成 \${j} x \${i} = \${j * i}。转写稿中数组求和案例强调“先打印每个元素看对不对,再累加”,这里同样可以先打印 i、j 验证行列,再输出算式。

样式 CSS:

css
span {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    border: 1px solid pink;
    margin: 2px;
    border-radius: 5px;
    box-shadow: 2px 2px 2px rgba(255, 192, 203, .4);
    background-color: rgba(255, 192, 203, .1);
    text-align: center;
    color: hotpink;
}

JavaScript:

javascript
 // 外层打印几行
for (let i = 1; i <= 9; i++) {
    // 里层打印几个星星
    for (let j = 1; j <= i; j++) {
        // 只需要把 ★ 换成  1 x 2 = 2   
        document.write(`
				<div> \${j} x \${i} = \${j * i} </div>
     `)
    }
    document.write('<br>')
}

九九乘法表效果图

易错点:算式顺序是 j x i,不是 i x j;笔记中 CSS 选择器写的是 span,而 JS 输出的是 <div>,实际运行时要注意选择器与标签一致,否则样式不生效。模板字符串中的换行和缩进可能带来额外空白,需在浏览器中预览调整。

调试与易错点汇总 ​

为什么需要:嵌套循环出错时,往往不是语法错,而是边界、换行位置、变量初始值错。

怎么想:转写稿主体讲的是数组遍历、求和、最大值,并没有直接讲循环嵌套;但其中可迁移的调试动作很明确:先小规模测试、打印循环变量、检查边界是否加等号、累加变量先设 0、最大值初始值取数组第一个元素而不是写死。转写稿里的“便离/遍利”应纠正为“遍历”,“缩引号/送引号”应纠正为“索引”,“佛循环/风循环”应纠正为“for 循环”,“and find/按例方案”应纠正为 undefined,“NAN”应纠正为 NaN。

怎么做:把三角型先改成 i <= 3、j <= i 测试;在循环里打印 i、j;检查 <br> 是否在外层;检查 j <= i 是否误写成 j < i。转写稿中“做一做就要测一测”同样适用于本节:先看小规模图案,再扩展到 5 行、9 行。

易错点:内外层变量重名;内层条件依赖外层时写错上界;换行放错层级;基本语法中使用中文括号;忘记浏览器预览导致 document.write 结果与预期不符。

数组是什么 ​

为什么需要:如果要保存班里多个同学的名字,用 name1、name2、name3 这样一个个变量会非常麻烦;数组可以在单个变量名下存储多个数据。

怎么想:数组(Array)是一种数据类型,属于引用数据类型;它的作用是在单个变量名下存储多个数据。

怎么做:把多个数据放进一个变量里,后续通过数组名统一管理。

易错点:不要因为数组里常放字符串,就以为数组只能放字符串;数组单元值可以是任意数据类型。

定义数组 ​

为什么需要:使用数组前,先要把数据存起来。

怎么想:数组用 [] 表示,多个数据之间用英文逗号分隔。

怎么做:

html
<script>
  // 1. 语法,使用 [] 来定义一个空数组
  // 定义一个空数组,然后赋值给变量 classes
  // let classes = []

  // 2. 定义非空数组
  let classes = ['小明', '小刚', '小红', '小丽', '小米']
</script>

数组里的“小明”“小刚”等称为数组单元,也叫数组元素。数组元素可以是字符串、数字、布尔值,甚至混合多种类型:

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>

易错点:数据之间要用英文逗号分隔;最后一个数据后可以不写逗号。

访问数组和数组索引 ​

为什么需要:存数据不是最终目的,关键是要能随时取出某个数据。

怎么想:数组按顺序存储,每个数据都有编号。编号从 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。

遍历数组 ​

为什么需要:如果要依次打印数组中的每个元素,写 arr[0]、arr[1]……很麻烦;元素多时更不现实。

怎么想:遍历数组就是把数组中每个数据都访问到,可以借助 for 循环。循环变量 i 正好可以充当索引,从 0 开始,到“数组长度减一”结束。数组长度用 数组.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,看到 0 1 2 3,说明循环次数正确;再把 console.log(i) 改成 console.log(arr[i]),就能依次取出数组元素。后来给数组增加一个元素,循环条件仍写 i < arr.length,程序不用改也能输出新增元素。

易错点:i 要从 0 开始;条件写 i < 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>

转写稿中演示了:查询 arr[2] 时,因为数组只有两个元素,所以返回 undefined;修改 arr[1] 后原位置被替换;写 arr[3] = '古丽扎娜' 时,索引 2 的位置会空出来,数组长度也变成 4。

易错点:修改时如果索引不存在,会变成新增元素并修改数组长度,容易产生空元素,不提倡这样做。

新增元素 ​

为什么需要:修改不存在的索引虽然能“加”元素,但不规范;需要专门的新增方法。

怎么想:向末尾新增用 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 返回的是新长度,不是新数组;它们会修改原数组。

删除元素 ​

为什么需要:数组元素需要删除时,不能只靠改索引,应使用删除方法。

怎么想:删除末尾用 pop,删除开头用 shift;它们都会修改原数组,并返回被删除的元素。

数组删除方法示意图

怎么做:

html
<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 返回的是被删除的元素,不是删除后的数组长度。

数组 splice 方法 ​

为什么需要:push、unshift 管开头和末尾,pop、shift 也管开头和末尾;如果要在中间删除或新增,就要用 splice。

怎么想:splice(start, deleteCount, item1, item2...) 从指定位置开始删除或新增,并修改原数组。start 是起始索引,从 0 计数;deleteCount 是删除个数,可省略;后面的参数是要新增的元素。

怎么做:

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>

易错点:起始位置是索引,从 0 开始;如果只删除到末尾,可省略第二个参数;如果是新增,第二个参数要写 0,不能省略。开头和末尾优先用 pop、shift、unshift、push,中间操作用 splice。

课件图示 ​

课件第46页:核心: 利用循环嵌套比较,根据索引号来交换变量 ①:外层循环是一共进行几轮相比较

课件第7页:l 循环嵌套: 一个循环语句里面又包含另一个循环语句 1. 循环嵌套 for(初

课件第19页:2.2 数组的基本使用 3. 遍历数组(重点) l 遍历数组:把数组中每个数据都

课件第41页:案例 根据数据生成柱形图 需求: 用户输入四个季度的数据,可以生成柱形图 分析:

课件第9页:练习 • 打印5行5列的星星 需求: 页面中打印出5行5列的星星 分析: ①:利

课件第10页:练习 • 打印三角形星星 需求:如图所示 分析: ①:利用双重for循环来做 ②

课件第35页:案例 手风琴案例 需求: 利用循环生成图片

课件第39页:案例 手风琴案例 小技巧: 利用循环拼接字符串 (原理跟累加和类似) ①:声明一

代码示例 ​

示例 1:循环嵌套 —— 九九乘法表 ​

js
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>循环嵌套 - 九九乘法表</title>
  <style>
    span {
      display: inline-block;
      width: 100px;
      padding: 5px 10px;
      border: 1px solid pink;
      margin: 2px;
      border-radius: 5px;
      box-shadow: 2px 2px 2px rgba(255, 192, 203, .4);
      background-color: rgba(255, 192, 203, .1);
      text-align: center;
      color: hotpink;
    }
  </style>
</head>
<body>
  <script>
    // 外层循环:打印几行
    for (let i = 1; i <= 9; i++) {
      // 里层循环:每行打印几个(个数跟着行号走)
      for (let j = 1; j <= i; j++) {
        // 只需要把 ★ 换成 1 x 2 = 2 这样的表达式
        document.write(`
          <span> ${j} x ${i} = ${j * i} </span>
        `)
      }
      // 一行结束再换行
      document.write('<br>')
    }
  </script>
</body>
</html>

要点解释:

  • for (let i = 1; i <= 9; i++) 是外层循环,控制“行”;for (let j = 1; j <= i; j++) 是里层循环,控制“每行几个”。里层的判断条件用的是外层变量 i,这就是三角形 / 乘法表的关键。
  • 外层循环循环一次,里层循环循环全部。所以换行 document.write('<br>') 必须写在里层循环的外面、外层循环的里面,写在里层里就会每个格子都换行。
  • 内层循环变量不要和外层重名(都用 let i 会报错 / 逻辑错乱),习惯上用 j。
  • 想改成三角型星星,只把 \${j} x \${i} = \${j * i} 换回 ★ 即可,循环结构完全不变。
  • 易错点:笔记里 CSS 选择器写的是 span,而 JS 里写的是 <div>,两者对不上样式不会生效;这里统一成 span,实际写代码时标签和选择器一定要保持一致。

示例 2:数组的声明、取值、遍历与查询修改 ​

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>数组基本使用</title>
</head>
<body>
  <script>
    // 1. 声明数组:用 [] 定义,多个数据用英文逗号分隔
    let names = ['小明', '小刚', '小红', '小丽', '小米']
    console.log(names)

    // 2. 数组取值:数组名[索引],索引从 0 开始
    console.log(names[0])  // '小明'
    console.log(names[1])  // '小刚'
    console.log(names[2])  // '小红'
    console.log(names[5])  // 查不到 -> undefined

    // 3. 遍历数组:把每个元素都访问到
    let arr = ['迪丽热巴', '古力娜扎', '佟丽丫丫', '玛尔扎哈', '哈尼克孜']
    for (let i = 0; i < arr.length; i++) {
      console.log(arr[i])
    }

    // 4. 查询与修改
    let stars = ['迪丽热巴', '古丽扎娜']
    console.log(stars[0])          // 查询:'迪丽热巴'
    stars[1] = '佟丽丫丫'           // 修改:数组[索引] = 新值
    console.log(stars)             // ['迪丽热巴', '佟丽丫丫']

    stars[3] = '古丽扎娜'           // 索引不存在 -> 变成新增,且改了数组长度(不提倡)
    console.log(stars)
    console.log(stars.length)      // 4
  </script>
</body>
</html>

要点解释:

  • 数组是引用数据类型,可以在单个变量名下存储多个数据;数组单元可以是任意数据类型(字符串、数字、布尔、甚至数组)。
  • 索引(下标)从 0 开始,所以遍历时 let i = 0,这是最容易写错的地方——写成 i = 1 会漏掉第一个元素。
  • 遍历条件写 i < arr.length,不要加等号。因为长度是 5,i < 5 得到 0~4,正好对应 5 个元素;写成 i <= arr.length 会多循环一次,最后一个取到 undefined。
  • 用 arr.length 拿长度,数组增删元素后循环不用改代码,这比写死数字更稳。
  • 查询不存在的索引返回 undefined(相当于声明了变量没赋值)。
  • 易错点:stars[3] = '古丽扎娜' 这种“修改”如果索引本身不存在,实际是新增元素,并且会修改数组长度、中间可能留下空元素(空白项),遍历和计算时容易出问题,所以一定要看准索引再赋值。

示例 3:数组求和、求平均值、求最大值 ​

js
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>数组求和 / 平均值 / 最大值</title>
</head>
<body>
  <script>
    let array = [2, 6, 1, 7, 4]

    // 第一步:声明两个变量,一定要给初始值 0
    let sum = 0
    let average = 0

    // 第二步:遍历数组,把每个元素累加到 sum 里
    for (let i = 0; i < array.length; i++) {
      sum += array[i]      // 等价于 sum = sum + array[i]
    }

    // 第三步:和求出来之后,再在循环外面求平均值
    average = sum / array.length

    console.log(`数组的累加和是:${sum}`)      // 20
    console.log(`数组的平均值是:${average}`)  // 4

    // ===== 求最大值 =====
    // 第一步:max 的初始值取数组的第一个元素
    let max = array[0]

    // 第二步:从第二个元素(索引 1)开始比较
    for (let i = 1; i < array.length; i++) {
      if (max < array[i]) {
        max = array[i]     // 我比你小,就把你的值拿过来
      }
    }

    // 第三步:输出最大值
    console.log(`数组的最大值是:${max}`)      // 7
  </script>
</body>
</html>

要点解释:

  • sum 必须初始化为 0。如果写成 let sum 不赋值,它就是 undefined,undefined + 数字 结果是 NaN,后面全错。
  • 累加写成 sum += array[i],这里的 array[i] 就是数组里每一个元素(i 从 0 开始正好和索引对上)。
  • 平均值一定要写在循环外面,等循环结束 sum 才是完整的和;写进循环里会拿到中间值。
  • 求最大值时 max 的初值取 array[0],比较循环从 i = 1 开始,省掉一次“自己和自己比”,这是笔记里的做法;如果 max 初始写 0,当数组全是负数时会出错。
  • 比较方向不能反:if (max < array[i]) max = array[i],只有“我比你小”才把大的换进来,这样 max 里始终是当前最大值。
  • 举一反三求最小值:把变量名改成 min,条件把 < 改成 >(if (min > array[i]) min = array[i])即可。

常见错误 ​

  1. 遍历时下标从 1 开始 / 用了 <=

    • 现象:第一个元素永远打印不出来,最后多打印一个 undefined;数组只有 5 项却循环了 5 次仍漏数据。
    • 原因:数组索引从 0 开始,arr.length 是“个数”而不是“最大下标”,最大下标是 length - 1。
    • 修法:固定写法 for (let i = 0; i < arr.length; i++),起始 0、条件用 <。
  2. 循环嵌套内外层用了同一个循环变量

    • 现象:外层只跑一次就结束,或输出行数、每行个数完全对不上。
    • 原因:内层 for (let i = ...) 与外层同名,内层每轮都重置并改写了外层正在用的计数器。
    • 修法:内层换名(j、k),且必须用 let 独立声明。
  3. 内层循环的上界写成了固定数字

    • 现象:想打印三角形、九九乘法表,结果出来一个规整的矩形,每行个数都一样。
    • 原因:内层条件写成 j <= 5 这类常量,没有和外层行号关联。
    • 修法:让内层上界跟着外层走,如 for (let j = 1; j <= i; j++);同时把 <br> / 换行写在内层循环结束后、外层循环体内,否则每个元素都换行。
  4. 累加变量不给初值,或把求和写进循环却把“除以长度”也写进循环

    • 现象:求和结果 NaN;平均值明显偏小且每次循环都在变。
    • 原因:let sum; 得到 undefined,undefined + 数字 = NaN;平均值在每轮循环里都被重算一次。
    • 修法:let sum = 0,循环内只做 sum += arr[i],平均值放到循环外:sum / arr.length。
  5. 求最大值时初值写 0,或比较方向写反

    • 现象:数组全是负数时最大值输出 0;想求最大值结果输出的是最小值。
    • 原因:初值 0 不是数组里的元素,负数都比它小,永远不更新;if (max > arr[i]) max = arr[i] 保留的是小的那个。
    • 修法:let max = arr[0],从 i = 1 开始,条件写 if (arr[i] > max) max = arr[i]。
  6. 用越界下标“新增”元素

    • 现象:arr[10] = 'x' 后 length 变成 11,中间一堆 undefined,遍历时参与运算又得到 NaN。
    • 原因:下标不存在时赋值不是正规的新增方式,会在中间留空洞并改写 length。
    • 修法:末尾用 push、开头用 unshift、中间用 splice(起始, 0, 新元素...);改元素前先确认下标确实存在。
  7. 搞混增删方法的返回值

    • 现象:let len = arr.pop() 拿到的不是长度;let arr2 = arr.push('a') 之后拿 arr2 去遍历直接报错。
    • 原因:push/unshift 返回新长度,pop/shift 返回被删除的元素,splice 返回被删元素组成的数组,四者都修改原数组。
    • 修法:需要新数组就继续用原数组变量;只需要长度时才接 push 的返回值。

练习 ​

  1. 倒三角:用循环嵌套在页面上打印 5 行 ★,第 1 行 5 个、第 5 行 1 个,每行结束后换行。(提示:行数递增,个数递减。)

  2. 带序号的点名:给定 let names = ['小明','小刚','小红','小丽'],遍历输出 第1位同学是:小明、第2位同学是:小刚……要求序号从 1 开始、名字从数组取。(提示:注意 i 与展示序号的关系。)

  3. 成绩统计:给定 let scores = [78, 45, 92, 60, 33, 88],一次遍历求出总分、平均分、最高分,以及不及格(< 60)的人数,分四行输出。

  4. 求最值及其位置:给定 let nums = [-8, -3, -25, -7],输出最大值、最小值,以及最大值在数组中的下标。(提示:先想清楚初值该放什么。)

  5. 增删改组合:给定 let arr = ['HTML','CSS','JS','Vue'],完成:①在末尾加 'React';②在开头加 'Web';③删掉 'CSS';④把 'JS' 改成 'JavaScript'。最后遍历输出整个数组,并打印最终长度。

原视频对照 ​

#视频时长
1数组基本使用10:03
2遍历数组08:38
3数组求和以及平均值案例08:17
4求数组最大值案例11:08
5操作数组之查询和修改数组元素07:38

小结 ​

  1. 数组遍历只有一种标准骨架:for (let i = 0; i < arr.length; i++),起始 0、条件 <,这两点错了后面全错。
  2. 循环嵌套的分工是固定的:外层决定“做几轮 / 几行”,内层决定“每轮做几次 / 每行几个”;内层跑完整整一轮,外层才前进一步。
  3. 内层循环的上界要不要跟外层变量挂钩,决定了你画出的是矩形还是三角形——这是嵌套题的第一判断点。
  4. 累加、计数、求最值都属于“三件套”:变量先给合理初值(sum = 0、max = arr[0]),循环内只更新,循环外才计算和输出。
  5. 求最大值的初值必须来自数组本身(arr[0]),从 i = 1 开始比较,才能兼容全负数;求最小值只需把比较符号反过来。
  6. 读不存在的下标得到 undefined,写不存在的下标会造出空洞并改变 length;所以“查”可以越界,“改”不能越界,“增”必须走 push / unshift / splice。
  7. 四个增删方法都会修改原数组,但返回值不同:push/unshift 给长度,pop/shift 给被删元素,splice 给被删元素数组——用错返回值是调试时最常见的坑。
  8. 凡是要“先遍历完才能算出来”的结果(总分、平均值、最值、人数),一定放在循环体之外,写进循环里必然错。