函数

128 阅读5分钟

函数

思考:如果想要获取多个不同数组中的最大值怎么办

答:函数

1.定义

函数 (function ),执行特定任务的代码块

函数可以把具有相同或相似逻辑的代码 “ 包裹 ” 起来,通过函数调用执行这些被 ‘’ 包裹 ‘’的代码逻辑,这样做有利于精简代码方便复用

2.函数的基本使用

2.1声明函数

image-20220401173701214.png 函数名命名规范

  • 和变量名基本一致

  • 尽量使用小驼峰式命名法

  • 前缀应该为动词

  • 命名建议:常用动词规定

image-20220401173919625.png

2.2调用函数

image-20220401180103085.png

注意点

  • 声明(定义)的函数必须调用才会真正被执行,使用()调用函数

  • 函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次

  • 我们曾经使用的alert(),parseInt ()这种名字后面跟小括号的本质都是函数的调用

代码如下:

 <script>
      // 1.声明函数
      function sayHi() {
        console.log("早上好");
        console.log("下午好");
        console.log("晚上好");
      }

      // 2.调用函数
      sayHi();
      sayHi();
      sayHi();
    </script>

2.3 函数封装 = 抽取

封装的函数不够灵活 无法复用 没有感受到 提高!!

 <script>
      // 1.声明函数,
      function getSum1() {
        let num1 = 1;
        let num2 = 2;
        console.log(num1 + num2);
      }
      // 2.调用函数
      getSum1();
    </script>

3.函数传参

函数传参可以提高函数的灵活性

3.1 有参数的函数声明

image-20220401182441332.png

注意点 :参数列表

  • 传入数据列表
  • 声明这个函数需要传入几个数据
  • 多个数据要用逗号隔开

3.2 有参数的函数调用

image-20220401182742645.png

调用函数时,需要传入几个数据就写几个,用逗号隔开

3.3 形参和实参

image-20220401183658532.png

  • 形参: 声明函数时写在函数名右边()里面的就叫形参(形式上的参数)
  • 声明定义的时候,形参只是参数占位
  • 在调用方法(用的时候肯定有括号的就讲方法)的时候,形参是一个变量
  • 相当于在方法中声明的局部变量,只有在方法内部可以使用,在方法外部使用,会报错
  • 实参: 调用函数时写在函数名右边()里面的就叫实参(实际上的参数)
  • 调用的时候,尽量让形参和实参顺序对应,数量对应,类型对应

小试牛刀案例1

需求:学生的分数是一个数组,计算每个学生的总分

代码如下

  <script>
      /* 需求:学生的分数是一个数组,计算每个学生的总分 */

      // 假设a同学的分数数组
      let arr1 = [10, 2, 30, 4, 50];
      //  假设b同学的分数数组
      let arr2 = [1, 20, 3, 40, 5];
      // 声明函数
      function getSum1(a) {
        // 声明一个变量总和sum
        let sum1 = 0;
        for (let index = 0; index < a.length; index++) {
          sum1 += a[index];
        }
        console.log(sum1);
      }
      // 调用函数
      getSum1(arr1);
      getSum1(arr2);
    </script>

小试牛刀案例2

需求:写一个函数,接收一个参数-数组,输出最大值、

代码如下

 <script>
      // 需求:写一个函数,接收一个参数-数组,输出最大值、
      // 2.第二步声明一个有参数的函数
      function getMax(a) {
        // 1.先完成数组输出最大值
        // let arr = [1, 3, 5, 7, 11];
        // 假设最大值的数组就等于旧数组中第0个元素
        let maxArr = a[0];
        for (let index = 0; index < a.length; index++) {
          if (a[index] > maxArr) {
            maxArr = a[index];
          }
        }
        
        console.log(maxArr);
      }
      // 3.第三步调用有参数的函数
      getMax([1, 3, 5, 7, 11]);
    </script>

小试牛刀案例3

需求:写一个函数,接收一个参数数组 ,计算数组中的奇数的和

代码如下

 <script>
      // 创建数组
      let arr1 = [1, 3, 5, 20, 40, 7];
      // 声明函数
      function getSum(a) {
        
        // 创建总和一开始为0  奇数总和 sum
        let sum = 0;
        for (let index = 0; index < arr1.length; index++) {
          // 奇数=当前数组元素 % 2 !== 0
          if (arr1[index] % 2 !== 0) {
            // 奇数和
            sum += arr1[index];
          }
        }
        console.log(sum);
      }
      // 调用函数
      getSum(arr1)
    </script>

4.函数返回值

定义 :函数执行后得到结果,结果是调用者想要拿到的(一句话,函数内部不需要输出结果,而是返回结果)

好处执行结果的扩展性更高,可以让其他的程序使用这个结果

return关键字可以实现返回值

注意点

  • return 变量
  • 一个函数只能返回一个变量,如果有多个值需要返回,可以将多个值包装到数组,返回这一个数组
  • return:可以中止函数,函数中运行到return后面的代码都不再执行,所以return如果想要返回结果,后面的数据不要换行写
  • 一个函数中只有一个return可以被执行
  • 调用的函数如果有返回值,可以定义一个变量用于接收这个函数的返回值
  • 函数返回了什么值,你就可以接收到什么值
  • 如果函数没有返回值,默认会返回undefined

小试牛刀案例1

需求. 求任意数组中的最大值并返回这个最大值

代码如下

<script>
      /* 需求. 求任意数组中的最大值并返回这个最大值
       */
      // 声明有参数的函数 ,a传参等于[1, 11, 2, 3, 44, 55, 6]
      function getMax(a) {
        let max = a[0];
        //  数组循环
        for (let index = 0; index < a.length; index++) {
          if (a[index] > max) {
            max = a[index];
          }
        }
        // 返回最大值
        return max;
      }
      //  调用有参数的函数
      // getMax([1, 11, 2, 3, 44, 55, 6]);

      // 函数max调用的返回值
      let max = getMax([1, 11, 2, 3, 44, 55, 6]);
      console.log(max);
    </script>

5.作用域

5.1定义

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

5.2 三种作用域

全局作用域:在script标签中声明的成员

函数作用域:局部作用域:在函数内部声明的成员

块级作用域:在{}中声明的成员

 <script>
      // script标签内的运行环境就是全局作用域
      let num = 100; // 全局作用域

      function getMax() {
        // 这个区域内就不属于全局作用域
        // 局部作用域 或者 也叫做 函数作用域
        let num2 = 200;
      }

      for (let index = 0; index < 4; index++) {
        // 块级作用域
      }

      while (true) {
        // 块级作用域
      }
      if (true) {
        // 块级作用域
      }
    </script>

5.3 变量的作用域

全局变量 :在任意的地方来访问

 <script>
      // 直接写在全局作用域下的变量 =  全局变量  在任意的地方来访问

      let num = 100; // 全局变量   在任何地方都可以访问 

      function getMax() {
        console.log('函数 访问全局变量', num);
      }

      getMax();

      for (let index = 0; index < 2; index++) {
        console.log('for循环内 块级作用域 访问全局变量', num);
      }

      if(true){
        console.log("if语句 也 可以访问全局变量",num);
      }
    </script>

局部变量:是在函数内部定义的变量 ;局部变量 不能在 它的大括号之外使用的,否则就会报错!!

 <script> 
      let msg = 10000; // 全局变量
      // 局部变量 
      function getMax() {
        // 声明一个数字
        let num = 200; // 局部变量
      }
      // 局部变量 不能在 超出它的大括号来使用
      console.log(num); // 会报错 
    </script>

块级变量 :就是我们在块级作用域内 定义的变量 ,类似局部变量,也是超出了自身的大括号 不能使用

  <script>
     	for (let index = 0; index < 2; index++) {
     // num 块级变量 
      	let num = 100;
      }
  	console.log(num);// 使用块级变量  出错!! 

    </script>

注意点

  • 有一种特殊情况是全局变量是局部变量或者块级变量 没有let 声明直接赋值的当全局变量看,我们强烈不提倡
  • 还有一种特殊情况,函数内部的形参可以当做局部变量看

5.4 作用域链

只是代码寻找变量的一种机制,规定就近原则,判断是要根据函数的定义来判断,而不是函数的调用

  • 首先先找自己的作用域num (没找到)

  • 往外部(父级)的作用域来找(没找到)

  • 继续往外部(父级)来找

  • 直到找到全局作用域 停止下来了

6.匿名函数

函数按照有没有名字 分成两种

  • 具名函数 有具体名字的

    // 具名函数  函数名称  func1
    function func1() {
     }
    
  • 匿名函数 没有名字 function () {}

    	function () {
          // 设置 页面的标题 =  月薪过万
        document.title = '月薪过万';
        // 设置 页面的背景颜色 =  黄色
        document.body.style.backgroundColor = 'yellow';
        }
    

    函数的表达式就是可以表示结果的一段代码

    写法如下: let fn = function(){}

自执行函数:匿名函数一起出现 通用的功能是 防止变量污染
	(function () {
	 let msg = 123;
 	// 设置 页面的标题 =  月薪过万
     //   document.title = '月薪过万';
  	// 设置 页面的背景颜色 =  黄色
 	document.body.style.backgroundColor = 'yellow';
   })();