JavaScript 基础 | Day04 函数


函数

函数:function,是被设计为执行特定任务代码块
说明:函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做可以实现代码复用,提高开发效率


1、函数使用

1.1 函数的基本使用语法

function 函数名()  {
       函数体  
 //函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
 }
 函数名()

例:

 // 1. 函数的声明
 function sayHi() {
   document.write(`你好~~~`)
 }
    // 2. 函数调用
    //注意:声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数
    sayHi()

1.2 函数的命名规范

  • 和变量命名基本一致
  • 尽量小驼峰命名法
  • 前缀应该为动词
  • 命名建议:常用动词约定
function getName() {}
function addSquares() {}

在这里插入图片描述

2.函数传参

2.1 为什么要有参数的函数

大家看下面这个函数:

function getSum()  {
    let num1 = 10
    let num2 = 20
    console.log(num1 + num2)
    }
getSum()    

思考:大家可以看出这样的函数只能求 10 + 20, 这个函数功能局限非常大

解决方法:要把计算的数字传到函数内

结论:若函数的完成功能需要调用者传入数据,那么就需要用有参数的函数

2.2 有参数的函数声明和调用

声明语法:

   function 函数名(参数列表) {
  //参数列表:传入数据列表;声明这个函数需要传入几个数据;多个数据之间用逗号隔开
    函数体
  }
 函数名(传递的参数列表)

单个参数

  function getSum(num1) {
    document.write(num1 *num1)
}
  getSum(9)

多个参数

  function getSum(num1,num2) {
       document.write(num1 + num2)
  }
  getSum(10,20)

在这里插入图片描述
形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
建议:开发中尽量保持形参和实参个数一致

2.3 函数练习

  1. 求 1~100的累加和 封装函数
  function getSum100() {
            let sum = 0
            for (let i = 1; i <= 100; i++) {
                sum += i
            }
            document.write(sum)
        }
        getSum100()
  1. 调用函数的时候传入两个实参,求两实参之间的累加和
 function getSum100(start, end) {
            let sum = 0
            for (let i = start; i <= end; i++) {
                sum += i
            }
            document.write(sum)
        }
        getSum100(1, 10)
        getSum100(10, 100)
  1. 拓展 函数封装求和
    return 返回值会在接下来的内容中详细介绍
    合理利用逻辑中断,解决 形参如果不被赋值,就是 undefined 的问题
 function getSum(x, y) {
            x = x || 0
            //如果 x 的布尔值为 true,则把 右边的x 赋值给 左边的x ,否则把 0 赋值给 x
            y = y || 0
            // 先计算 x + y 再返回
            return x + y   
        }
        let sum = getSum(1, 2)
        // let num1 = prompt('请输入')
        document.write(sum)

4.函数封装-求学生总分

    <script>
  // 需求:学生的分数是一个数组,计算每个学生的总分
      // 分析:
       // (1) 封装一个求和函数
       // (2) 传递过去的参数是一个数组
       // (3)函数内部遍历数组求和
        function getScore(arr) {
            // arr = [99, 10, 100]
            let sum = 0
            for (let i = 0; i < arr.length; i++) {
                sum += arr[i]
            }
            document.write(sum)
        }
        // 调用函数
        getScore([88, 99, 100])
        getScore([90, 80, 100])
    </script>

3.函数返回值

3.1为什么要让函数有返回值

函数内部不需要输出结果,而是返回结果

我们前面已经接触了很多的函数具备返回值:

let result1 = prompt('请输入您的年龄")
let result2 = parseInt('111')

只是这些函数是JS内置的,我们直接就可以使用
当然有些函数就没有返回值例如 alert()
所以根据需求来设定需不需要返回值。

3.2 用return返回数据

当函数需要返回数据出去时,用return关键字

基本使用

 function getSum(x, y) {
    return x + y
 }
 let num =getSum(10,30)
 document.write(num)

3.3 函数返回值的细节

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
  • return会立即结束当前函数
  • return后面不接数据或者函数内不写return,函数的返回值是undefined

3.4函数返回值练习

    <script>
        // 求数组最大值的函数
        function getArrMaxValue(arr) {
            // 声明一个max变量
            // 把数组第一个值给 max
            let max = arr[0]
            // 开始遍历数组并比较
            for (let i = 1; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i]
                }
            }
            // 返回这个最大值
            return max
        }
        let maxplus = getArrMaxValue([1, 5, 8, 9, 3])
        document.write(`数组的最大值是${maxplus}`)
    </script>

4.作用域

4.1作用域的概述

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这
个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
在这里插入图片描述

4.2 变量的作用域

在JavaScript中,根据作用域的不同,变量可以分为 全局变量局部变量块级变量
在这里插入图片描述
4.2.1 全局变量

//1.全局变量 全局能用
   let num = 10
        console.log(num)  //10
        function fn() {
            console.log(num) 
        }
        fn()   //10

4.2.2 局部变量

大坑: 局部变量必须是函数里面声明过(let)的变量

// 2. 在局部作用域下,变量是 局部变量
// 函数内的变量,只能给内部使用,函数外面不能使用
  function fn() {
            let num = 20
            console.log(num)
            function fn1() {
                console.log(num)
                let num2 = 30
            }
            fn1()
            // console.log(num2) // 控制台输出结果: num2 is not defined
        }
        fn()
        console.log(num)  //控制台输出结果:  num is not defined

4.2.3 块级变量

let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问

  for (let i = 0; i < 5; i++) {
            console.log(i)
        }
        console.log(i)   //控制台报错:Uncaught ReferenceError: i is not defined

4.3 变量访问原则-作用域

变量访问原则:在能够访问到的情况下 先局部 局部没有在找全局

作用域链:根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访
问,就称作作用域链

4.3.2 变量访问原则-作用域 (小练习)

// 作用域链:采取就近原则的方式来查找变量最终的值
let a = 1
function fn1() {
      let a = 2
      let b = '22'
      fn2()
      function fn2() {
           let a = 3
           fn3()
           function fn3() {
                 let a = 4
                 console.log(a) //a的值 4
                 console.log(b) //b的值 22
        }
    }
}
fn1()

5.匿名函数

函数可以分为 具名函数匿名函数

   // 声明
 function fn() {
  }
   //调用
 fn()

匿名函数 :将匿名函数赋值给一个变量,并且通过变量名称进行调用 我们将这个称为函数表达式

let fn = function () {
    //函数体
}
fn()   //函数名
//其中函数的形参和实参使用跟具名函数一致

5.1立即执行函数

场景介绍:避免全局变量之间的污染
多个立即执行函数要用 ; 隔开,要不然会报错

// 立即执行函数  立即执行, 无需调用
//方式一:
   (function () {console.log(111)})()//方式二:
 (function () {console.log(111)}())//注意: 多个立即执行函数要用 ; 隔开,要不然会报错
// 第一个小括号放的 形参   第二个小括号放的是实参
(function (x, y) {
             console.log(x + y)
         })(1, 2)

6.综合案例

    <script>
    //需求: 用户输入秒数,可以自动转换为时分秒
    //分析:
    //(1): 用户输入总秒数
    //(2):计算时分秒(封装函数) 里面包含数字补0
    //(3):打印输出


        // 1.  用户输入
        let second = +prompt('请输入总的秒数:')
        // 2. 计算时间  封装函数
        function getTimes(t) {
            // 小时:  h = parseInt(总秒数 / 60 / 60 % 24)
            // 分钟:  m = parseInt(总秒数 / 60 % 60)
            // 秒数: s = parseInt(总秒数 % 60)
            let h = parseInt(t / 60 / 60 % 24)
            let m = parseInt(t / 60 % 60)
            let s = parseInt(t % 60)
            h = h < 10 ? '0' + h : h
            m = m < 10 ? '0' + m : m
            s = s < 10 ? '0' + s : s
            return `计算之后的时间是${h}小时${m}${s}`
        }
        // 3. 打印输出
        let str = getTimes(second)
        document.write(str)
        // document.write(str)
    </script>

7.自问自答

1.函数不调用会执行吗?如何调用函数?

答:函数不调用自己不执行,调用方式:函数名()

2.函数的复用代码和循环复用代码有什么不同?

函数的复用代码随时调用,随时执行,可重复调用
循环代码写完即执行,不能很方便的控制执行位置

3. 函数参数可以分为那两类?怎么判断他们是那种参数?

函数可以分为形参实参

  • 函数声明时,小括号里面的是形参,形式上的参数
  • 函数调用时,小括号里面的是实参,实际的参数
  • 尽量保持形参和实参的个数一致

4. 为什么要让函数有返回值

  • 函数执行后得到结果,结果是调用者想要拿到的(函数内部不需要输出结果,而是返回结果)
  • 对执行结果的扩展性更高,可以让其他的程序使用这个结果

5. JS 中作用域分为哪三种?

  • 全局作用域。函数外部或者整个script 有效
  • 局部作用域。也称为函数作用域,函数内部有效
  • 块级作用域。 { } 内有效

6. 变量访问原则是什么?

作用域链:采取就近原则的方式来查找变量最终的值

7.立即执行函数需要调用吗? 有什么注意事项呢?

  • 无需调用,立即执行,其实本质已经调用了
  • 多个立即执行函数之间用分号隔开
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心平气荷.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值