Skip to content

1-12函数及应用(二) ​

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

学习目标 ​

  • 能封装接收数组参数的求和函数,在函数内遍历累加并 return 结果,并为数组参数设置空数组默认值以避免未传参报错。
  • 能说明并验证 return 的关键细节:立即结束当前函数、return 与返回值不换行、无 return 时默认返回 undefined。
  • 能封装求数组最大值的函数,使用循环比较求出最大值并返回,且能将返回值保存到变量中复用。
  • 能封装判断数组是否包含指定元素的函数,使用 flag 标记、循环比较、找到后改为 true 并 break,最终返回布尔值。
  • 能封装查找数组元素下标的函数,找到时返回当前索引并 break,找不到时返回 -1,并为数组参数设置默认值。
  • 能使用浏览器断点调试,用 F11 进入函数内部查看参数与变量变化,用 F10 单步跳过函数,并说明退出函数与单步调试按钮的作用。

知识点 ​

函数的基本使用:先封装,再调用 ​

为什么需要: 相同或相似逻辑重复写,既啰嗦又难维护。函数把代码“包裹”成可复用代码块,核心价值是复用。
怎么想: 先声明函数,把逻辑放进函数体;再通过“函数名()”调用。只声明不调用,函数体不会执行。
怎么做:

javascript
// 声明一个最简单的函数:没有形参,也没有返回值
function sayHi() {
  console.log('嗨~')
}

// 调用:函数名()
sayHi()
sayHi() // 可以重复调用

易错点: 函数名命名规则与变量一致,采用小驼峰,常以动词开头;调用必须带 ()。笔记中的完整示例还包含 HTML 页面结构,核心仍是“声明 + 调用”。

函数的整体认知:参数进,返回值出 ​

函数整体认知示意图

为什么需要: 只有固定逻辑的函数不够灵活,函数需要接收外部数据,并把处理结果交给调用者。
怎么想: 把函数想成“加工机器”:参数是输入,return 是输出。
怎么做:

javascript
function sum(参数1, 参数2) {
  return 结果
}
console.log(sum(1, 2)) // 输出函数返回的结果

易错点: 多个参数用逗号分隔;return 把结果返回给调用者,不是直接打印。

函数参数:形参、实参与个数不匹配 ​

形参和实参传递示意图

为什么需要: 通过传参,让同一个函数处理不同数据,函数才灵活多变。
怎么想: 声明时小括号里是形参,可理解为函数内部变量;调用时小括号里是实参,实参数据会传给形参。alert('打印')、parseInt('11px')、Number('11') 本质上都是函数调用传参。
怎么做:

javascript
function sum(x, y) {
  return x + y
}
console.log(sum(1, 2))    // 3
console.log(sum(1))       // NaN,y 为 undefined
console.log(sum(1, 2, 3)) // 3,多余实参被忽略

易错点: 形参过多会自动补 undefined;实参过多会被忽略。开发中提倡实参与形参个数统一。

逻辑中断与默认参数:处理缺参更严谨 ​

为什么需要: 调用函数时可能漏传参数,直接运算会得到 NaN,甚至访问 undefined.length 报错。
怎么想: 逻辑与 && 左边为假就中断;逻辑或 || 左边为真就中断。可用 x = x || 0 兜底;形参也可直接写默认值。
怎么做:

javascript
console.log(false && 1 + 2) // false
console.log(true || 1 + 2)  // true

function sum(x = 0, y = 0) {
  return x + y
}
console.log(sum()) // 0
console.log(sum(undefined, undefined)) // 0
console.log(sum(1, 2)) // 3

易错点: false、0、''、undefined 等都会触发中断;默认参数只在缺参或实参为 undefined 时生效。默认参数主要处理形参,逻辑中断还能处理更多需求。

函数返回值:把内部结果交给外部 ​

为什么需要: 函数体执行完后,外部需要拿到内部处理结果。
怎么想: 用 return 把结果返回给调用者;没有返回值时,函数默认返回 undefined。
怎么做:

javascript
function fn() {}
console.log(fn()) // undefined

function sum(x, y) {
  return x + y
  console.log('我不会执行')
}
console.log(sum(1, 3)) // 4

易错点: return 会立即结束当前函数,后面代码不执行;return 与被返回表达式不要换行,否则相当于自动补分号;break 退出循环或 switch,return 退出函数。

作用域:变量可用范围与就近原则 ​

为什么需要: 限制变量可用范围,增强可靠性,减少命名冲突。
怎么想: 全局作用域作用于整个 script 或独立 js 文件;局部作用域包括函数作用域和 {} 块级作用域。访问变量时先局部,局部没有再找全局,即“就近原则”。
怎么做: 在函数内声明的变量是局部变量;形参也可看作局部变量。
易错点: 函数内变量不声明直接赋值,会当全局变量看,强烈不推荐。

匿名函数、函数表达式与立即执行函数 ​

为什么需要: 有些函数只用一次或需要避免全局污染,不必都写成具名函数。
怎么想: 匿名函数没有名字,不能直接使用;赋值给变量后通过变量名调用,就是函数表达式。立即执行函数(IIFE)定义后马上执行。
怎么做:

javascript
let fn = function() {
  console.log('函数表达式')
}
fn()

(function(){ console.log('IIFE') })();
(function(){ console.log('IIFE2') }());

易错点: 函数表达式必须先定义后使用;多个立即执行函数之间要用 ; 隔开,否则可能报错。

用封装案例串起来:求和、最大值、查找 ​

为什么需要: 把数组求和、求最大值、判断元素是否存在、查索引封装起来,才能在不同数据上复用。
怎么想: 求和:遍历数组累加并 return sum;最大值:先令 max = arr[0],循环比较更新;判断存在:设 flag = false,找到改 true 并 break;查索引:设 index = -1,找到记录当前 i 并 break。
怎么做: 转写稿强调给数组形参默认空数组,避免没传参时读 undefined.length 报错:

javascript
function sumArr(arr = []) {
  let sum = 0
  for (let i = 0; i < arr.length; i++) {
    sum += arr[i]
  }
  return sum
}
console.log(sumArr([1, 2, 3])) // 6
console.log(sumArr()) // 0

易错点: 没传数组时不要直接读 arr.length;找到后及时 break 提高性能;返回值常赋给变量保存,后续直接用变量更方便。

断点调试:用 F11 进入函数内部 ​

为什么需要: 只看结果很难判断形参是否接到实参、循环是否按预期执行。
怎么想: F10 是下一步,但不进入函数;F11 可进入函数内部。打中断点后要刷新页面。
怎么做: 在调用处打断点,刷新后按 F11 进入函数;鼠标悬停可查看形参和实参;遇到 break 会退出循环,随后到 return;还可使用“退出当前函数”按钮。
易错点: 别把 break 和 return 混淆;调试时重点掌握 F10 与 F11 的差别。

综合案例目标:把总秒数转换成时分秒 ​

综合案例效果图

为什么需要:实际页面里经常要把“总秒数”显示成 时:分:秒,例如倒计时、活动计时。直接显示总秒数不直观,所以需要转换并补 0。
怎么想:先让用户输入总秒数,再写一个函数专门负责换算,最后把结果拼成页面结构。转写稿里封装数组求和时也强调“先封装函数,再处理数据并 return 结果”,本节同理。
怎么做:用 prompt 获取输入,用 + 转成数字;封装 getTime(t = 0);函数返回带 span 的模板字符串;用 document.write 输出。
易错点:prompt 得到的是字符串,不转换可能影响计算;用户取消输入时不能把逻辑写乱;函数要 return 结果,不能只在函数里 console.log。

计算公式:先理解除法、取余和取整 ​

为什么需要:时分秒之间是 60 进制,不能直接把总秒数拆成三段,必须分别算出小时、分钟、秒。
怎么想:小时用“总秒数 ÷ 60 ÷ 60”,分钟用“总秒数 ÷ 60 后对 60 取余”,秒用“总秒数对 60 取余”。parseInt 用来取整。
怎么做:

  • 小时:h = parseInt(t / 60 / 60 % 24)
  • 分钟:m = parseInt(t / 60 % 60)
  • 秒数:s = parseInt(t % 60)
    易错点:不要把 %24 漏掉或写错位置;parseInt 只取整数部分;计算顺序要按除法和取余的实际含义理解,不要凭感觉拆。

封装 getTime:参数、返回模板字符串、补 0 ​

为什么需要:转换逻辑要复用,封装成函数后,换一个总秒数也能直接算。转写稿中讲函数封装时反复强调“参数传进来、内部处理、把结果返回给调用者”。
怎么想:函数接收总秒数 t,内部算出 h、m、s,再判断是否小于 10,小于就补 '0'。最后返回 HTML 字符串,而不是只打印。
怎么做:用三元表达式补 0,例如 h = h < 10 ? '0' + h : h,并记得把结果重新赋值给 h。返回模板字符串:
<span class="hour">\${h}</span>...
易错点:只写 h < 10 ? '0' + h : h 却没有赋值,页面仍不会补 0;返回的模板字符串要包含完整 span 结构;默认参数 t = 0 可让函数在无参时也不至于直接出错。

页面输出:document.write 与结构拼接 ​

为什么需要:计算结果是数据,页面需要的是带 class 的 HTML 结构,才能套用 CSS 样式。
怎么想:先得到 getTime(totalSeconds) 的返回值 str,再把 str 放进 .timer 容器中。
怎么做:用 document.write 输出整段 .box 结构,把 \${str} 插入 .timer 内部。
易错点:document.write 会直接写页面,适合本案例演示;拼接时注意模板字符串反引号和 ${};不要把 str 当成普通文本放进错误位置。

用断点调试验证函数执行 ​

为什么需要:只看结果不容易发现参数是否传对、循环或函数内部哪一步出错。转写稿中讲断点调试时强调:F10 是下一步但不进入函数,F11 可以进入函数内部。
怎么想:在调用 getTime 前后观察 totalSeconds 和 str,进入函数后观察 t、h、m、s 的变化。
怎么做:打开开发者工具 Sources,打断点,刷新页面;用 F11 进入函数,鼠标悬停查看变量值;确认补 0 后变量是否变成字符串。
易错点:转写稿里的“阿瑞、er瑞、aree”应纠正为数组 array;“形参/实参”不要混;break 退出循环或 switch,return 退出函数;undefined 不是“安迪芬”,false/true 不是“佛斯/处”。

完整代码 ​

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>综合案例-转换时间案例</title>
  <style>
    .box {
      position: relative;
      width: 190px;
      height: 260px;
      color: #fff;
      background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
    }

    .title {
      width: 100%;
      text-align: center;
      font-size: 30px;
      font-weight: 700;
      padding-top: 31px;
    }

    .count {
      margin-top: 90px;
      font-size: 14px;
      text-align: center;
    }

    .timer {
      margin-left: auto;
      margin-right: auto;
      width: 130px;
      height: 30px;
      margin-top: 10px;
      display: block;
    }

    .timer span {
      position: relative;
      float: left;
      width: 30px;
      height: 30px;
      text-align: center;
      background-color: #2f3430;
      margin-right: 20px;
      color: white;
      font-size: 20px;
    }

    .timer span:nth-child(-n+2)::after {
      content: ":";
      display: block;
      position: absolute;
      right: -20px;
      font-weight: bolder;
      font-size: 18px;
      width: 20px;
      height: 100%;
      top: 0;
    }

    .timer span:last-child {
      margin-right: 0;
    }
  </style>
</head>

<body>
  <!-- <div class="box">
    <div class="title">计算时间</div>
    <div>
      <div class="count">转换为时分秒</div>
      <div class="timer">
        <span class="hour">01</span>
        <span class="minute">22</span>
        <span class="second">58</span>
      </div>
    </div>
  </div> -->

  <script>
    // 转换时分秒案例 
    // 计算公式:计算时分秒
    // 小时:  h = parseInt(总秒数 / 60 / 60 % 24)
    // 分钟:  m = parseInt(总秒数 / 60 % 60)
    // 秒数:   s = parseInt(总秒数 % 60) 

    // 1. 用户输入总的秒数
    let totalSeconds = +prompt('请您输入总的秒数:')

    // 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
    function getTime(t = 0) {
      // 转换小时
      let h = parseInt(t / 60 / 60 % 24)
      // 转换分钟
      let m = parseInt(t / 60 % 60)
      // 转换秒数
      let s = parseInt(t % 60)
      // 数字补0
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      console.log(h, m, s)
      return `
        <span class="hour">${h}</span>
        <span class="minute">${m}</span>
        <span class="second">${s}</span>
      `
    }
    let str = getTime(totalSeconds) // 实参
    console.log(str)
    // 3. 页面打印输出
    document.write(`
       <div class="box">
        <div class="title">计算时间</div>
        <div>
          <div class="count">转换为时分秒</div>
          <div class="timer">
            ${str}
          </div>
        </div>
      </div>
    `)
  </script>
</body>

</html>

课件图示 ​

课件第4页:函数-Function 函数: 是可以被重复使用的代码块 作用:函数可以把具有相

课件第6页:函数基本使用 定义一个函数并不会自动执行它,需要调用函数 2. 调用函数 利用关

课件第7页:总结 总结 1. 函数是什么?有什么好处? Ø 可以被重复使用的代码块 Ø 代码

课件第11页:1.2 函数整体认知 问题:这样的函数只能求 10 + 20, 而且结果只能函数

课件第12页:1.2 函数整体认知 l 函数语法 l 说明: Ø 函数参数,如果有多个则用逗号

课件第15页:1.3 函数参数 Ø 形参:声明函数时小括号里的叫形参(形式上的参数) Ø 实参

课件第17页:总结 总结 1. 函数中实参在哪里?形参在哪里? Ø 函数调用时,小括号里面的是

课件第19页:1.3 函数参数 - 默认参数 默认参数:可以给形参设置默认值 说明:这个默认值

代码示例 ​

示例 1:函数的声明、调用、参数与返回值细节 ​

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 函数声明、参数与返回值</title>
</head>
<body>
  <script>
    // 1. 声明(定义)最简单的函数:既没有形式参数,也没有返回值
    function sayHi() {
      console.log('嗨~')
    }
    // 函数调用:函数名()
    sayHi()
    sayHi() // 可以重复调用,多少次都可以

    // 2. 形参和实参个数不匹配
    function sum(x, y) {
      return x + y
    }
    console.log(sum(1, 2))    // 3
    console.log(sum(1))       // NaN:x=1,y 没有给值默认是 undefined,1 + undefined = NaN
    console.log(sum(1, 2, 3)) // 3:多余的实参会被忽略

    // 3. 逻辑中断解决形参没有传值的问题
    function sum2(x, y) {
      x = x || 0
      y = y || 0
      return x + y
    }
    console.log(sum2())     // 0
    console.log(sum2(1, 2)) // 3

    // 4. 默认参数(主要处理形参,比逻辑中断更简单)
    function sum3(x = 0, y = 0) {
      return x + y
    }
    console.log(sum3())                     // 0
    console.log(sum3(undefined, undefined)) // 0
    console.log(sum3(1, 2))                 // 3

    // 5. return 的细节
    // 5.1 return 结束函数,后面的代码不会执行
    function fn1() {
      return 1 + 3
      console.log('我不会执行')
    }
    console.log(fn1()) // 4

    // 5.2 return 和被返回的结果不要换行(内部相当于自动补了分号)
    function fn2() {
      return
      1 + 3
    }
    console.log(fn2()) // undefined

    // 5.3 没有 return,默认返回 undefined
    function fn3() {}
    console.log(fn3()) // undefined
  </script>
</body>
</html>

要点解释与易错点

  • function 函数名() {} 只是声明,必须用 函数名() 调用才会真正执行;函数名采用小驼峰、尽量用动词。
  • 形参过多会自动补 undefined(sum(1) 得 NaN);实参过多会被忽略(sum(1,2,3) 得 3)。开发中提倡实参与形参个数统一。
  • 逻辑中断:false && anything、true || anything 会中断,返回左侧值;否则返回右侧值。x = x || 0 就是利用 undefined || 0 得到 0。
  • 默认参数 x = 0 只在没有实参或实参是 undefined 时生效。
  • return 会立即结束函数,后面的代码不会执行;return 与返回值之间不能换行,否则相当于 return;,函数返回 undefined。
  • 区分 return 与 break:return 退出的是函数,break 退出的是循环或 switch。

示例 2:函数封装练习(求和 / 求最大值 / 判断元素存在 / 查找索引) ​

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>函数封装练习</title>
</head>
<body>
  <script>
    // 1. 封装数组求和函数
    function sumArr(arr = []) {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      return sum
    }
    console.log(sumArr([1, 2, 3]))    // 6
    console.log(sumArr([1, 2, 3, 4])) // 10
    console.log(sumArr())             // 0

    // 2. 封装求数组最大值函数
    function arrMax(arr = []) {
      let max = arr[0]
      for (let i = 0; i < arr.length; i++) {
        if (max < arr[i]) {
          max = arr[i]
        }
      }
      return max
    }
    let max = arrMax([1, 2, 3, 4, 5])
    console.log(max)                        // 5
    console.log(arrMax([11, 23, 38, 4, 5])) // 38
    console.log(arrMax())                   // undefined

    // 3. 封装判断数组是否存在某个元素(flag 技巧)
    function some(ele, arr = []) {
      let flag = false
      for (let i = 0; i < arr.length; i++) {
        if (ele === arr[i]) {
          flag = true
          break // 找到了就没必要继续循环,提高性能
        }
      }
      return flag
    }
    let arr = ['苹果', '香蕉', '橘子', '荔枝', '梨']
    let re = some('荔枝', arr)
    console.log(re) // true
    let re1 = some('榴莲', arr)
    console.log(re1) // false

    // 4. 封装查找元素在数组中的索引(找不到返回 -1)
    function findIndex(ele, arr = []) {
      let index = -1
      for (let i = 0; i < arr.length; i++) {
        if (ele === arr[i]) {
          index = i // 把当前索引号记录下来
          break
        }
      }
      return index
    }
    console.log(findIndex(10, [1, 5, 10, 20, 8])) // 2
    console.log(findIndex(8, [1, 5, 10, 20, 8]))  // 4
    console.log(findIndex(88, [1, 5, 10, 20, 8])) // -1
  </script>
</body>
</html>

要点解释与易错点

  • 封装思路固定为四步:声明函数(传元素 / 数组)→ 声明初始变量 → 循环遍历比较 → return 变量。
  • arr = [] 默认参数很关键:用户不传数组时,arr 是 undefined,arr.length 会报 Cannot read properties of undefined (reading 'length');给空数组后返回 0 / undefined,程序更严谨。
  • flag 技巧:预设 false,找到就改成 true 并 break;找不到时变量原封不动,直接 return,不需要 if else。查找索引同理,初值设为 -1。
  • break 必须在 if 内部、循环内部,不能写在循环外,且它是退出循环而不是退出函数。
  • 求最大值时 let max = arr[0],若传空数组则 max 为 undefined,这是正常现象。
  • 把返回值存进变量(如 let max = arrMax(...))后再复用,比每次写一长串调用更清晰——和 let age = prompt(...) 是同一个道理。

示例 3:综合案例——秒数转换时分秒 ​

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>综合案例-转换时间案例</title>
  <style>
    .box {
      position: relative;
      width: 190px;
      height: 260px;
      color: #fff;
      background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
    }

    .title {
      width: 100%;
      text-align: center;
      font-size: 30px;
      font-weight: 700;
      padding-top: 31px;
    }

    .count {
      margin-top: 90px;
      font-size: 14px;
      text-align: center;
    }

    .timer {
      margin-left: auto;
      margin-right: auto;
      width: 130px;
      height: 30px;
      margin-top: 10px;
      display: block;
    }

    .timer span {
      position: relative;
      float: left;
      width: 30px;
      height: 30px;
      text-align: center;
      background-color: #2f3430;
      margin-right: 20px;
      color: white;
      font-size: 20px;
    }

    .timer span:nth-child(-n+2)::after {
      content: ":";
      display: block;
      position: absolute;
      right: -20px;
      font-weight: bolder;
      font-size: 18px;
      width: 20px;
      height: 100%;
      top: 0;
    }

    .timer span:last-child {
      margin-right: 0;
    }
  </style>
</head>
<body>
  <script>
    // 转换时分秒案例
    // 计算公式:计算时分秒
    // 小时:  h = parseInt(总秒数 / 60 / 60 % 24)
    // 分钟:  m = parseInt(总秒数 / 60 % 60)
    // 秒数:  s = parseInt(总秒数 % 60)

    // 1. 用户输入总的秒数
    let totalSeconds = +prompt('请您输入总的秒数:')

    // 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
    function getTime(t = 0) {
      // 转换小时
      let h = parseInt(t / 60 / 60 % 24)
      // 转换分钟
      let m = parseInt(t / 60 % 60)
      // 转换秒数
      let s = parseInt(t % 60)
      // 数字补0
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      console.log(h, m, s)
      return `
        <span class="hour">${h}</span>
        <span class="minute">${m}</span>
        <span class="second">${s}</span>
      `
    }
    let str = getTime(totalSeconds) // 实参
    console.log(str)

    // 3. 页面打印输出
    document.write(`
       <div class="box">
        <div class="title">计算时间</div>
        <div>
          <div class="count">转换为时分秒</div>
          <div class="timer">
            ${str}
          </div>
        </div>
      </div>
    `)
  </script>
</body>
</html>

要点解释与易错点

  • +prompt(...) 前面的 + 是隐式转换,把用户输入的字符串转成数字,否则后面参与除法运算会出问题。
  • 三个公式必须用 parseInt 取整:小时除以 60/60 后 %24(超过一天从头算),分钟 %60,秒数 %60。
  • 补 0 用三元表达式 h < 10 ? '0' + h : h,注意 '0' + h 得到的是字符串,所以三个变量都被改成了字符串,模板字符串拼接时不受影响。
  • 形参 t = 0 是默认参数,用户没输入(或取消输入)时返回 00 00 00,不会因为 undefined 运算得到 NaN。
  • 函数用 return 返回的是模板字符串形式的 HTML 结构,不是直接操作 DOM;调用者拿到结果再 document.write 输出,体现"函数负责处理数据、调用者负责使用结果"的封装思想。
  • 注意 return 后面的反引号模板字符串不能和 return 换行,否则函数会返回 undefined。
  • CSS 中的 ./images/bg.png 是背景图占位,图片不存在时布局仍正常,只是没有背景图。

常见错误 ​

  1. 定义完函数页面毫无反应 现象:写完 function sayHi(){...} 后控制台什么也没有。 原因:只声明未调用,函数体不会执行。 修法:定义之后写 sayHi(),需要执行几次就调用几次。

  2. return 拿到的结果是 undefined 现象:sum(1,3) 输出 undefined 而不是 4。 原因:return 和 x + y 写成了两行,JS 自动补分号,return 提前结束。 修法:return x + y 写在同一行。

  3. return 后面的代码永远不打印 现象:函数里 return 之后的 console.log 从未执行过。 原因:return 会立即结束当前函数(它退的是函数,不是循环,循环该用 break)。 修法:把要执行的语句移到 return 之前,或直接删掉。

  4. 不传参数就报错或算出 NaN 现象:调用 sumArr() 报 Cannot read properties of undefined (reading 'length'),调用 sum() 得到 NaN。 原因:没有实参,形参值是 undefined,undefined.length 与 1 + undefined 都不成立。 修法:形参给默认值,如 function sumArr(arr = [])、function sum(x = 0, y = 0)。

  5. 判断"数组中有没有某元素"永远返回 true 现象:查一个明显不存在的元素,结果还是 true,或结果只跟数组第一个元素有关。 原因:return flag 写在了 for 循环体内,第一轮就返回了。 修法:循环内只负责改 flag(命中就置 true 并 break),return flag 放到循环外。

  6. 函数表达式先调用后定义报错 现象:fn is not a function 或 Cannot access 'fn' before initialization。 原因:let fn = function(){} 是赋值语句,按代码顺序执行,没有函数声明的提升。 修法:先定义,后调用。

  7. 连续写两个立即执行函数报错 现象:第二个 IIFE 报 "is not a function"。 原因:前一个 IIFE 结尾没写分号,被解析成对返回值的继续调用。 修法:每个 IIFE 后面补 ;。

  8. 调试时按 F10 进不去函数内部 现象:断点停在调用行,再按 F10 直接跳到下一行,看不到函数体执行。 原因:F10 是"跳过函数"。 修法:改用 F11 进入函数体;想提前结束当前函数用退出函数按钮。

练习 ​

  1. 求最小值:仿照 arrayMax 封装 arrayMin(arr = []),返回最小值。分别用 [11,23,38,4,5]、[7]、不传参三种情况验证,并说明第三种为什么合理。
  2. 统计次数:封装 countOf(arr = [], target),返回 target 在数组中出现的次数,找不到返回 0。要求 return 只出现在循环之外。
  3. 两种兜底对比:分别用默认参数和逻辑中断各写一个 sum,使 sum()、sum(1)、sum(1,2) 都不返回 NaN,并说明两种写法各自的适用场合。
  4. 查最后下标:封装 lastIndexOf2(arr = [], ele),返回元素最后一次出现的下标,找不到返回 -1。要求用"预设变量 → 循环比对 → 循环外 return"的套路,且不能一找到就 break。
  5. 时间案例改造:把 getTime 改成不传参时按 0 秒处理,并把补零逻辑抽成独立的 padZero(n) 函数由 getTime 调用;再用两个连续的 IIFE 把整段代码包起来,验证分号问题。

原视频对照 ​

#视频时长
1封装数组求和函数07:13
2函数返回值细节07:39
3封装求数组最大值函数08:59
4封装判断数组是否存在某个元素14:54
5封装函数返回数组元素下标06:56
6断点调试-进入函数调试07:24

小结 ​

  1. 函数不调用等于没写;调用一次执行一次,调用 N 次执行 N 次。
  2. 传参本质是"把实参赋值给形参",个数不匹配不报错但会得到 undefined / NaN,用默认值兜底比事后补逻辑更省事。
  3. return 是函数的唯一出口:既带回结果,也立刻终止函数;它退的是函数,循环用 break,两者别混。
  4. 默认参数只解决"没传或传 undefined",逻辑中断能做的事更多,按场景选,别硬套。
  5. 想用函数的结果,必须 return 并用变量接住;把返回值存进变量是后续复用结果的标准写法。
  6. 判断类函数(存在性、下标)统一四步:预设结果变量 → 循环比对 → 命中改值并 break → 循环外统一 return。
  7. 匿名函数不能直接跑:要么赋给变量(先定义后使用),要么用 IIFE 包起来,多个 IIFE 之间必须用分号隔开。
  8. 调试时 F10 跳过函数、F11 进入函数、退出函数按钮提前收工;进函数第一件事是看形参有没有接到值。