Javascript基础day06

60 阅读3分钟

Javascript基础day06

JS - 函数

函数

• 为什么需要函数

函数:

  • function,是被设计为执行特定任务的代码块

说明:

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

函数的声明语法

1648693092296.png

!

1648693108170.png

函数的调用语法

1648693132290.png

1648693151200.png

体验函数场景

<script>
      let arr1 = [1, 3, 2, 66, 33, 22];
      let arr2 = [1, 3, 2, 663, 33, 22];
      let arr3 = [1, 3, 2, 665, 33, 22];

      let max1 = getMax(arr1);
      let max2 = getMax(arr2);
      let max3 = getMax(arr3);

      console.log(max1, max2, max3);

      function getMax(arr) {
        let max = arr[0];
        for (let index = 0; index < arr.length; index++) {
          if (arr[index] > max) {
            max = arr[index];
          }
        }
        return max;
      }
    </script>

• 函数使用

通过这段代码 封装 成函数,体会函数的好处

 <script>
      // 1 函数的声明
      function sayHi() {
        console.log('你好');
        console.log('你真好');
        console.log('你真TM好');
      }

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

1648694238905.png

函数封装

<script>
      // 封装的函数不够灵活 无法复用 没有感受到 提高!! 
      // 计算 3 + 2 的和
      // 计算 1-50 的和

      // 只能计算 100 + 1
      function calcSum1() {
        let a = 100;
        let b = 1;
        console.log(a + b);
      }

      // 计算 3 + 2 的和
      function calcSum3() {
        let a = 3;
        let b = 2;
        console.log(a + b);
      }

      // 只能计算 1-100 和
      function calcSum2() {
        let sum = 0;
        for (let index = 1; index <= 100; index++) {
          sum += index;
        }
        console.log(sum);
      }

      // 计算 1-50 的和
      function calcSum3() {
        let sum = 0;
        for (let index = 1; index <= 50; index++) {
          sum += index;
        }
        console.log(sum);
      }

      calcSum1();
      calcSum2();

      // console.log();
      // document.write()
      // alert(789);
    </script>

1648693756823.png

<script>
      // 1 声明函数 -  输出  99乘法表
      function calcNum() {
        for (let index = 1; index <= 9; index++) {
          for (let index1 = 1; index1 <= index; index1++) {
            let num = index1 * index;
            document.write(`<span>  ${index1} * ${index} = ${num}     </span>`);
          }
          document.write('<br/>');
        }
      }

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

1648694337920.png

• 函数传参

1. 为什么要有参数的函数

1648694373695.png

2.有参数有函数声明和调用

1648694391448.png

1648694406033.png

3. 形参和实参

1648694428080.png

  • 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
  • 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
  • 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
  • 开发中尽量保持形参和实参个数一致
  • 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参
 <script>
      // 声明函数
      function getSum(num1, num2) {
        // num1 = 100
        // num2 = undefined
        console.log(num2);
        document.write(num1 + num2);
        // 100 + undefined
      }
      // function getSum(a, b) {
      //   document.write(a + b);
      // }

      // getSum(10, 20);
      // getSum(100, 200);
    </script>

1648695412738.png

1648694488647.png

1648694501135.png

• 函数返回值

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

1648694679795.png

1648694692568.png

使用场景

<script>
      // 函数 参数的最大值
      function getMax(n1, n2) {
        if (n1 > n2) {
          return n1;
        } else {
          return n2;
        }
      }

      // 通过 console.log 帮我打印
      // let num1 = getMax(1, 3);
      // console.log(num1);
      // let num1 = getMax(1, 3);
      console.log(getMax(1, 3));

      // 通过 document.write  帮我打印
      // let num2 = getMax(2, 4);
      document.write(getMax(2, 4));

      // 通过 alert 帮我打印
      // let num3 = getMax(6, 8);
      alert(getMax(6, 8));
    </script>

2.用return返回数据

1648694715784.png

细节:

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
  • return会立即结束当前函数
  • 函数可以没有 return,这种情况函数默认返回值为 undefined
 <script>
      // function getMax() {}

      // function getSum() {}

      // // 这个num1 就是  函数getMax调用的返回值 ( num1 = 1 2 。。)

      // // let num2 = getSum();

      // let num1 = getMax();// 我们自己写的函数 只能返回 undefined
      // let num3 = parseInt(1.3);// js自己内部写的 返回值  1

      // console.log(num3); //

      function getMax() {
        // 100 就是 函数在执行完毕的时候 会返回的数据
        return 300;
      }

      let num1 = getMax(); // num1 =100

      console.log(num1);
    </script>

使用场景

<script>
      // 函数 参数的最大值
      function getMax(n1, n2) {
        if (n1 > n2) {
          return n1;
        } else {
          return n2;
        }
      }

      // 通过 console.log 帮我打印
      // let num1 = getMax(1, 3);
      // console.log(num1);
      // let num1 = getMax(1, 3);
      console.log(getMax(1, 3));

      // 通过 document.write  帮我打印
      // let num2 = getMax(2, 4);
      document.write(getMax(2, 4));

      // 通过 alert 帮我打印
      // let num3 = getMax(6, 8);
      alert(getMax(6, 8));
    </script>

1648695033807.png

• 作用域

1.作用域概述

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

1648695120807.png

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

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

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

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

2.变量的作用域

在JavaScript中,根据作用域的不同,变量可以分为

1648695169738.png

 <script>
      //  在同一个作用域内 声明两个同样变量 就会出错。

      // 全局变量
      // let num = 100;

      // let num = 200;

      // function getMax() {
      //   let num = 100;
      // }

      // function getMin() {
      //   let num = 200;
      // }

      // for (let index = 0; index < 2; index++) {
      //   let num = 100;
      //   console.log("第一次循环,",num);
      // }

      // for (let index = 0; index < 2; index++) {
      //   let num = 100;
      //   console.log("第二次循环,",num);
      // }

      let arr1 = [1, 3, 4, 33, 22];

    
      function getMax(arr) {
        let max = arr[0];
        for (let index = 0; index < arr.length; index++) {
          if (arr[index] > max) {
            max = arr[index];
          }
        }
        return max;
      }
      function sdfdf(params) {
        
      }
    </script>
 <script>
      
      
      let num = 100;

      function getMax() {
        // let num =200;

        console.log(num); //  200   就近原则  寻找变量的时候 优先找自己的作用域 
      }

      getMax();

    </script>
<script>
      // let num = 100;

      function getMax() {
        // let num = 200;

        for (let index = 0; index < 1; index++) {
          // let num = 300;
          console.log(num);
        }
      }

      getMax();
    </script>

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);// 使用块级变量  出错!! 


      // {
      //   let num =10;
      // }
      // {
      //   console.log(num);
      // }

      /* 
      小结
      1 分类     分成两类即可  
      1 全局变量
        直接放在 script标签内的变量
      2 局部变量 用大括号包起来的变量
        1 函数内部变量
        2 块级变量 
      
       */
    </script>

4.变量访问原则-作用域链

  • 只要是代码,就至少有一个作用域
  • 写在函数内部的局部作用域
  • 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
  • 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链

1648719253569.png

案例

1648695302799.png

1648695302799.png

 <script>
      // 从函数的定义出发 依据 就近原则 来寻找变量即可 
      
      
      let num = 100;
      function func1() {

        let num = 200;
        
        function fun2() {
          console.log(num);
        }
        
        fun2();
      }

      func1(); //   输出什么 
    </script>

1648695319001.png

<script>
      // let num = 100;
      // function func1() {
      //   let num = 200;
      //   fun2();
      // }

      // function fun2() {
      //   let num = 300;
      //   console.log(num); // 300
      // }

      // func1();

      // 判断当前变量 输出是什么  
      // 就近原则   判断是要根据 函数的定义 来判断 而不是函数的调用 
      // 函数的定义 代码位置来判断  100  这个!! 
   

      let num = 100;
      function func1() {
        let num = 200;
        // 函数的调用 
        fun2();
      }

   

      // 函数的定义-声明 
      function fun2() {
        console.log(num);
      }

      func1();
    </script>

• 匿名函数

1648695718290.png

1.匿名函数

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

1648695759088.png

<script>
      // 函数按照有没有名字 分成两种
      // 有名字 具名函数
      // 没有名字 匿名函数

      // 具名函数  函数名称  func1
      // function func1() {
      // }

      // 匿名函数  = function () {}; 匿名函数 了解即可 

      //    let func2 = function () {};  叫做 函数表达式 
      // 表达式 可以表示结果的一段代码  函数表达式  了解 
      let func2 = function () {
        console.log("123");
      };


      // 调用
      func2();
    </script>

使用场景

1648695807082.png

2. 立即执行函数

场景介绍: 避免全局变量之间的污染

1648695849167.png

<script>
      /* 
      自执行函数 =  匿名函数一起出现  通用的功能是   防止变量污染 
      函数在定义的同时 直接就执行了 

      用在哪里呢  
      适合做一次性的任务- 不希望这个函数可以得到复用!!! 
        函数包装多段代码  让程序比较简洁

      1 页面打开时候
        1 设置 页面的标题 =  月薪过万
        2 设置 页面的背景颜色 =  黄色 
      
       */

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

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

      // console.log(msg);
    </script>

综合案例

1648695875176.png

分析方法:

1648695897624.png