JavaScript概念(六)

153 阅读3分钟

JavaScript

函数

一、什么是函数,为什么需要函数?

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

2.函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。(可以实现代码复用,提高开发效率)

3、体验函数魅力(案例---筛选多个数组的最大值)

    <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>

二、函数使用

1.目标:掌握函数语法,把代码封装起来

2.语法

function 函数名() {
   函数体
}

function sayHi() {
   document.write(`sayhi`)
}

3.函数名命名规范

①和变量命名基本一致 ②尽量小驼峰式命名法 ③前缀应该为动词 ④命名建议:常用动词约定

4.函数调用语法

//函数调用,这些函数体内的代码逻辑会被执行
函数名()

//函数一次声明可以多次调用,每一次函数调用函数体里面的代码会重新执行一次
sayhi()
sayhi()
//alert()、parseInt()也属于函数调用


    <script>
      //函数声明
      function sayHi() {
        console.log("你好");
        console.log("你真好");
        console.log("你真tm的好");

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

5.函数体

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

function sayHi() {
   console.log(`嗨`);
}
sayHi()

6.案例-九九乘法表

    <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>

7.封装

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

如:CSS里面,通过取类名将相同属性的属性及属性值写在一起

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

// 只能计算 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();
      calcSum3();

      // console.log();
      // d
ocument.write()
      // alert(789);

三、函数传参

1.为什么需要传参函数?

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

②提高函数的灵活性

2.语法

function 函数名(参数列表) {
   函数体
}

//单个参数
function getSquare(num1) {
document.write(num1*num1)
}
//多个参数
function getSquare(num1,num2) {
document.write(num1+num2)
}

    <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>

3.形参和实参(开发中尽量保持形参和实参个数一致)

①形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)

②实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)

③参数中间用“逗号”隔开

function getSum(num1, num2) {
        console.log(num2);
        document.write(num1 + num2);
      }

getSum(10, 20);
getSum(100, 200);

4.传参封装求和

需求:采取函数封装的形式:输入2个数,计算两者的和,打印到页面中

function getSum(x,y) {
   x=x || 0
   y=y || 0
console.log(x+y)
}
getSum(1,2)


// 数组求和
    <script>
      function getSum(arr) {
        let sum = 0;
        for (let index = 0; index < arr.length; index++) {
          sum += arr[index];
        }
        console.log(`总分:${sum}`);
      }
      let arr1 = [2, 5, 7, 8, 14, 26];
      let arr2 = [3, 5, 9, 17, 14, 26];

      getSum(arr1);
      getSum(arr2);
    </script>

四、函数返回值return

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

因为函数被设计为执行特定任务的代码块,把计算后的结果处理方式写死了,内部处理了。把处理结果返回给调用者,当调用某个函数,这个函数会返回一个结果出来。

2.用return返回数据

①语法

return 数据

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

3.return细节

①在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用 ②函数内部只能运行到 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写 ③return会立即结束当前函数 ④函数可以没有 return,这种情况函数默认返回值为 undefined

4.案例(一)

<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>

案例(二)

<script>
      let arr1 = [1, 3, 4, 33, 22];
      //   声明一个函数 用来计算数组最大值 且最大值 返回
      function getMax(arr) {
        let max = arr[0];
        for (let i = 0; i < arr.length; i++) {
          if (arr[i] > max) {
            max = arr[i];
          }
        }
        return max;
      }
      let max = getMax(arr1);
      console.log(max);
      //   声明一个函数 用来计算数组最小值 且最小值 返回
      function getMin(arr) {
        let min = arr[0];
        for (let i = 0; i < arr.length; i++) {
          if (arr[i] < min) {
            min = arr[i];
          }
        }
        return min;
      }
      let min = getMin(arr1);
      console.log(min);
    </script>

5.return补充

<script>
      /* 
      1 不能同时执行多次return 第一个return生效 
      2 函数内部 如果写了return ,那么它下面的代码就不会执行!! 
      3 如果一个函数 没有写return 相当于 写了 return undefined
       */
      function getMax() {
        return undefined;
      }

      let num = getMax();
      console.log(num);
    </script>

五、作用域

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

2.作用域分为:全局作用域、局部作用域、块级作用域

//全局作用域
整个 script 标签内部或者一个独立的 js 文件


//局部作用域
作用于函数内的代码环境,也叫函数作用域

//块级作用域
块作用域由 { } 包括,if语句和for语句里面的{ }等

3.变量作用域分为:全局变量、局部变量、块级变量

//全局变量
全局变量在变量定义之后区域可以访问和修改

//局部变量
局部变量只能在当前函数内部访问和修改

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

4.案例-变量作用域

①全局变量

    <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>

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

采取就近原则的方式来查找变量最终的值

6.变量的使用

<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>

7.函数的嵌套使用

    <script>
      function func1() {
        console.log("func1");

        func2();
      }

      function func2() {
        console.log("func2");
        func3();
      }

      function func3() {
        console.log("func3");
      }

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

8.作用域链测试

①测试一

    <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>

②测试二

    <script>
      // 从函数的定义出发 依据 就近原则 来寻找变量即可

      let num = 100;
      function func1() {
        let num = 200;

        function fun2() {
          console.log(num);
        }

        fun2();
      }

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

六、匿名函数

1.语法

①具名函数

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

②匿名函数

function() {}

let fn=function() {}

2.匿名函数使用场景:避免全局变量之间污染

方式一:(function () { console.log(11) })();

方式二:(function () { console.log(11) })();

// 不需要 调用 立刻执行
    <script>
      // 函数按照有没有名字 分成两种
      // 有名字 具名函数
      // 没有名字 匿名函数

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

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

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

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

七、自执行函数

    <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>