Skip to content

回顾 数组(Day6 1/3) ​

本页对应 Day06_JavaScript,共 7 段视频,约 1 小时 10 分。

学习目标 ​

  • 能说明数组的元素、索引、创建方式、读写、遍历、添加删除、多维数组及类数组特性,并完成相应基础操作。
  • 能使用倒序遍历和字符串拼接实现字符串翻转,并将其封装为带标准注释、参数和返回值的函数。
  • 能使用循环、取模和条件判断求出所有三位水仙花数。
  • 能设计并实现质数判断逻辑,使用标记变量或提前返回封装成返回布尔值的函数,并输出指定区间内所有质数。
  • 能使用嵌套循环、空格与星号拼接规则,在控制台输出指定行数的等腰三角形。
  • 能使用循环、取模和三元运算符将 1–50 按每行 10 个输出到页面,并对个位数补零。

知识点 ​

数组回顾:概念、读写与稀疏数组 ​

为什么需要:数组用来保存“值的有序集合”,后续做求和、最值、遍历都依赖它。转写稿里的“耳瑞”应纠正为 Array,“less”应纠正为 length,“suppice”应纠正为 splice。

怎么想:先抓三个概念:元素、索引、长度。索引从 0 开始且连续;读不存在的元素得到 undefined;给不存在的索引赋值可能产生稀疏数组。

怎么做:创建可用 [] 直接量,也可用 Array();添加删除可用 push/unshift/splice 与 pop/shift/splice,也可改 length。遍历时用 for 按下标逐个处理。

易错点:不要故意制造稀疏数组;读取“存在但无值”的元素与读取不存在元素都可能得到 undefined;字符串只是“类数组”,可按索引读、有 length,但不能像数组一样修改。

函数概念与创建方式 ​

为什么需要:函数把一堆散装代码封装起来,便于复用。转写稿强调函数也是 JS 数据类型,typeof 得到 function,比数组的 object 更特殊。

怎么想:函数由函数名、参数、函数体、返回值组成。函数名本质上是变量;参数是传入的原材料;返回值是计算结果。要区分“返回”和“输出”:return 不等于 console.log。

怎么做:重点掌握两种创建方式:function 函数名(){} 与 var fn = function(){}。转写稿中“functionction”应纠正为 Function 构造函数,属于了解内容。

易错点:函数调用表达式有值,这个值就是返回值;不写 return 时返回 undefined;标准注释可用 @param、@returns 说明参数和返回值。

翻转字符串案例:倒序遍历与拼接 ​

为什么需要:练习字符串索引、循环倒序和函数封装。转写稿明确:先建空字符串,再从原字符串末尾往前遍历,把字符拼到新字符串。

怎么想:正着遍历是从 0 到 length-1;倒着遍历就从 length-1 到 0,所以循环条件要 i >= 0。

怎么做:

js
function reverseString(str) {
  var newStr = '';
  for (var i = str.length - 1; i >= 0; i--) {
    newStr += str[i];
  }
  return newStr;
}
console.log(reverseString('hello'));

易错点:起始下标必须 length-1;条件不能写成 >0,否则漏掉第一个字符;封装后要 return,否则调用处拿不到结果。

水仙花数:取百十个位再判断 ​

为什么需要:练习循环、取整、取余和单项分支。转写稿说三位数从 100 到 999,逐个取出百位、十位、个位判断。

怎么想:水仙花数是“各位数字立方和等于原数”。百位用 Math.floor(n/100),十位用 Math.floor(n%100/10),个位用 n%10。

怎么做:

js
for (var n = 100; n <= 999; n++) {
  var a = Math.floor(n / 100);
  var b = Math.floor(n % 100 / 10);
  var c = n % 10;
  if (a*a*a + b*b*b + c*c*c === n) {
    console.log(n);
  }
}

易错点:十位不是 n/10;判断成立才输出,否则什么都不做,单项分支即可。

质数判断与函数封装:标记变量与提前 return ​

为什么需要:质数判断综合训练循环、取余、break、标记变量和函数返回值。转写稿中“得级变量”应纠正为“标记变量”。

怎么想:从 2 循环到 number/2 即可,超过一半的数不可能整除它。一旦 number % i === 0,就不是质数;循环结束仍没被整除,才是质数。

怎么做:封装时可用提前 return false,循环后 return true:

js
function isPrime(num) {
  for (var i = 2; i <= num / 2; i++) {
    if (num % i === 0) {
      return false;
    }
  }
  return true;
}

易错点:不要在循环里直接输出“是质数”,否则会输出多次;return 会立即结束函数;2 是最小质数,循环不执行时保持“是质数”的结论。

控制台三角形与数字阵列:拼字符串、按规律换行 ​

为什么需要:练习嵌套循环、找规律和输出格式控制。转写稿强调控制台一行只能写一个 console.log,所以星号要先拼成一个字符串。

怎么想:三角形第 n 行空格数是 rows-n,星号数是 2*n-1;数字阵列每输出 10 个换行,个位数补 0。

怎么做:

js
var rows = 5;
for (var n = 1; n <= rows; n++) {
  var str = '';
  for (var i = 0; i < rows - n; i++) str += ' ';
  for (var i = 0; i < 2*n - 1; i++) str += '*';
  console.log(str);
}

数字阵列:

js
for (var i = 1; i <= 50; i++) {
  var n = i < 10 ? '0' + i : i;
  document.write(n + ' ');
  if (i % 10 === 0) document.write('<br>');
}

易错点:控制台空格手打即可,不要混用 HTML 换行;document.write 用于页面输出,console.log 用于控制台;补 0 时 '0'+i 是字符串拼接,不能写成数字 0+i。

本节知识结构 ​

先把这一节要回顾的骨架保留下来,后面逐块展开。

text
1. 数组
   1.1 概念: 元素、索引
   1.2 创建数组(声明数组)
   1.3 读写数组中的元素
   1.4 稀疏数组
   1.5 遍历数组
   1.6 数组添加元素
   1.7 数组删除元素
   1.8 多维数组
   1.9 字符串的数组特性 / 类数组、伪数组

2. 函数
   2.1 函数是js中一种数据类型
   2.2 函数的组成
       函数名、函数体、参数、返回值
   2.3 创建函数
       ① function 关键字方式
       ② 表达式方式(直接量方式)
       ③ Function 函数  对应 Array、Number、String、Boolean
       ④ Function 构造函数

数组概念:元素与索引 ​

为什么需要:数组用来把一组有关联的值按顺序放在一起,避免写大量零散变量。
怎么想:数组是“值的有序集合”,里面的成员叫元素,每个元素有位置编号,叫索引。
怎么做:索引从 0 开始,必须是连续数字;用 arr[0]、arr[1] 这样的形式定位元素。
易错点:索引不是从 1 开始;元素和索引不是一回事。读取不存在的元素会得到 undefined,但这不代表数组里真的有一个 undefined 元素。

创建数组与读写元素 ​

为什么需要:先有数组对象,才能读写元素。
怎么想:创建数组最常用直接量 [];也可以用 Array()。读是 arr[i],写是 arr[i] = 值。
怎么做:例如 var arr = [10, 20, 30];,读 arr[1] 得 20,写 arr[1] = 200 就修改了第二个元素。
易错点:给不存在的、且与前面不连续的索引赋值,会产生稀疏数组;读取“存在但无值”的元素,同样得到 undefined。转写稿里说“浏览器给面子自动生成”,理解时要纠正为:这是读取规则返回 undefined,不是凭空生成了真实元素。

稀疏数组与 length ​

为什么需要:理解稀疏数组,才能避免数组出现大量空洞。
怎么想:索引不连续、把 length 改大、用 Array(数字) 只传一个数字参数,都可能产生空位。
怎么做:尽量用 arr[arr.length] = 值 追加,保证索引连续;不要随意把 length 改大。
易错点:Array(5) 不是创建 [5],而是创建长度为 5 的空数组;读取空位元素得到 undefined。

遍历数组与增删元素 ​

为什么需要:遍历用于求和、找最大值最小值、筛选等;增删用于维护数据。
怎么想:遍历用 for 配合 arr.length;添加可用 arr[arr.length]=值、push、unshift、splice;删除可用缩小 length、pop、shift、splice。
怎么做:尾部追加用 push,头部添加用 unshift,指定位置增删用 splice;删除最后一个用 pop,删除第一个用 shift。
易错点:pop、shift 一次只删一个;splice 既能添加也能删除,参数顺序要清楚;用 length 删除会直接截断末尾元素。

多维数组与字符串的数组特性 ​

为什么需要:多维数组表达表格、矩阵;字符串常被误当数组操作。
怎么想:数组元素如果还是数组,就是多维数组;字符串有索引和 length,所以像数组,但不是数组。
怎么做:多维用 arr[0][1] 访问;字符串可用 str[i] 读字符、str.length 取长度。
易错点:字符串只能读,不能像数组那样通过索引修改;它叫类数组/伪数组,英文常写 like array。

函数是数据类型与函数组成 ​

为什么需要:函数把一段代码封装起来,重复调用,避免复制粘贴。
怎么想:函数在 JS 中也是一种数据类型,和数组同属对象类型;typeof 函数 得到 "function"。函数由函数名、函数体、参数、返回值组成。函数名本质上是变量名,函数体是要执行的代码,参数是传入的原材料,返回值是计算结果。
怎么做:调用函数写 函数名(实参),这个整体是函数调用表达式,表达式的值就是返回值。
易错点:输出不等于返回。console.log 只是输出;return 才是把结果交给调用处。函数里执行到 return 后,后续代码不再执行。

创建函数的四种方式与调试推导 ​

为什么需要:不同写法帮助理解“函数是数据类型”,也便于选择常用写法。
怎么想:最常用是 function 关键字和函数表达式;Function 函数/构造函数了解即可,它们和 Array、Number、String、Boolean 一样,既有普通函数用法,也有构造函数用法。
怎么做:关键字方式如 function fn(a){ return a; };表达式方式如 var fn = function(a){ return a; };。
易错点:表达式方式能明显看出“函数名是变量”;关键字方式更像其他语言。不要死记代码,要跟一遍执行过程。

转写稿里的调试过程很典型:翻转字符串时,先建空串 newStr,再让循环变量从 str.length - 1 递减到 0,每次 newStr += str[i],最后返回 newStr。质数判断时,若在循环里直接写 else 输出,会输出很多遍;正确思路是先用标记变量默认“是质数”,一旦发现能整除就改成“不是质数”并 break,循环结束后再下结论。封装成函数后,更可直接 return false 提前结束函数,循环走完仍没被推翻,再 return true。控制台三角形则抓住“第 n 行星号数 2n-1、空格数 rows-n”,每行只拼一个字符串再 console.log。数字阵列中每 10 个换行用 i % 10 === 0 判断,个位数补 0 可用 i < 10 ? '0' + i : i。这些案例都说明:先想逻辑,再组合语法,最后用输出验证。

课堂画面 ​

课堂画面 1

课堂画面 2

课堂画面 3

课堂画面 4

课堂画面 5

课堂画面 6

代码示例 ​

代码段1:翻转字符串函数

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>翻转字符串</title>
</head>
<body>
<script>
  /**
   * 翻转字符串
   * @param {string} str 要翻转的字符串
   * @returns {string} 翻转好的字符串
   */
  function reverseString(str) {
    var newStr = '';
    for (var i = str.length - 1; i >= 0; i--) {
      newStr += str[i];
    }
    return newStr;
  }

  var msg = '高小乐去钓鱼';
  console.log(reverseString(msg));
  console.log(reverseString('高小乐'));
</script>
</body>
</html>

关键行与易错点:

  • for (var i = str.length - 1; i >= 0; i--):倒着遍历原字符串,注意必须遍历到 0。
  • newStr += str[i]:把当前字符拼接到新字符串中,拼接一次长度增加一次。
  • return newStr:返回翻转结果;只写 return 不会自动输出,需要 console.log 或赋值使用。
  • 易错点:循环条件写成 i > 0 会漏掉第一个字符。

代码段2:封装判断质数函数并输出 100–200 的质数

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>判断质数</title>
</head>
<body>
<script>
  /**
   * 判断一个数字是否是质数
   * @param {number} number 要判断的数字
   * @returns {boolean} true 表示是质数,false 表示不是质数
   */
  function isPrime(number) {
    for (var i = 2; i <= number / 2; i++) {
      if (number % i === 0) {
        return false;
      }
    }
    return true;
  }

  for (var n = 100; n <= 200; n++) {
    if (isPrime(n)) {
      console.log(n);
    }
  }

  console.log(isPrime(2));
  console.log(isPrime(21));
</script>
</body>
</html>

关键行与易错点:

  • if (number % i === 0) return false;:一旦能被某个数整除,就直接返回 false,并结束函数。
  • for (var i = 2; i <= number / 2; i++):循环到一半即可,超过一半的数不可能整除它。
  • return true 写在循环外:循环结束都没有被推翻,才说明是质数。
  • 易错点:不能在 for 循环里直接写 else 输出“是质数”,否则会输出很多遍;2 是质数,因为循环不会执行,最后返回 true。

代码段3:控制台输出等腰三角形

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>控制台三角形</title>
</head>
<body>
<script>
  var rows = 5;

  for (var n = 1; n <= rows; n++) {
    var str = '';

    for (var i = 0; i < rows - n; i++) {
      str += ' ';
    }

    for (var i = 0; i < 2 * n - 1; i++) {
      str += '*';
    }

    console.log(str);
  }
</script>
</body>
</html>

关键行与易错点:

  • 外层 for (var n = 1; n <= rows; n++):控制行数。
  • for (var i = 0; i < rows - n; i++):每行前面的空格数量是“总行数 - 当前行号”。
  • for (var i = 0; i < 2 * n - 1; i++):每行星号数量是 2n - 1。
  • 易错点:控制台一行只能用一个 console.log(str),不能每颗星输出一次;控制台空格直接写 ' ',不要写 &nbsp;。

常见错误 ​

  1. 翻转字符串时循环从 0 到 length,结果多拼一个 undefined → 边界写成 length-1 或倒序时从 length-1 开始且包含 0 → 明确“起始值、终止条件、是否包含终点”。
  2. 质数判断在 for 循环里直接输出“是质数/不是质数” → 循环未结束就下结论,导致重复输出或误判 → 用标记变量或函数内 return,循环结束后只输出一次结论。
  3. 在质数判断中以为 break 能结束外层循环 → break 只结束当前所在循环 → 外层需要继续判断时改用标记变量;函数场景可直接 return false 结束函数。
  4. 函数内执行 return false 后还期待后续 return true 执行 → 误以为 return 只返回值不终止函数 → 明确 return 会立即结束当前函数,后续代码不执行。
  5. 控制台三角形只拼星号不拼空格,得到直角三角形 → 忽略“每行前面空格数 = 总行数 - 当前行号” → 同一行先拼空格再拼星号,一行只用一个 console.log。
  6. 数字阵列补零时写成 0 + i → 数字相加不会得到 "01" → 用字符串 "0" + i,或三元表达式按条件补零。
  7. 数字阵列想每 10 个换行却依赖页面自动换行 → 自动换行不受控 → 判断 i % 10 === 0 时输出 <br>。

练习 ​

  1. 封装 reverseString(str),完成字符串翻转;要求分别测试普通字符串、空字符串、单字符字符串。
  2. 封装 isPrime(num),只返回布尔值;再用它输出 100~200 之间所有质数,要求每个结果只输出一次。
  3. 输出一个等腰三角形,行数由变量控制;要求同时控制空格数与星号数,并说明当前行号、空格数、星号数之间的关系。
  4. 输出 1~50 的数字阵列:每行 10 个、个位数前补 0、每满 10 个换行。
  5. 输出所有三位水仙花数;要求先明确百位、十位、个位的取法,再写判断条件。

原视频对照 ​

#视频时长
1回顾14:50
2翻转字符串案例11:12
3取水仙花数01:25
4质数判断15:24
5封装判断质数的函数13:23
6控制台输出三角形09:16
7数字陈列04:54

小结 ​

  1. 数组读写、添加、删除、遍历要围绕“索引是否连续、长度是否变化”检查结果。
  2. 函数封装的价值在于把一段可复用逻辑收进函数体,调用处只关心参数和返回值。
  3. 翻转字符串的关键不是死记代码,而是明确遍历方向和拼接顺序。
  4. 质数判断的关键是“循环中只排除,循环结束后再下结论”。
  5. 标记变量适合“循环结束后统一判断”的场景;函数中的 return 适合“满足条件立即结束”的场景。
  6. 控制台图形题要先找行号与空格数、星号数的数量关系,再落到循环和字符串拼接。
  7. 数字阵列题要同时处理三个细节:范围、补零、按固定个数换行。
  8. 写代码前先捋逻辑,再组合语法;逻辑不清时,代码越写越乱。