函数

含义说明:

引用类型之一
function 是被设计为执行特定任务的代码块
可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行
优点:有利于精简代码方便复用,提高开发效率

定义声明使用

  1. function 函数名(){
  2. 函数体(代码块)
  3. }
  4. 1. 函数名规则和变量一样,规范不同,一般是前缀动词,变量是名词;
  5. 尽量小驼峰式命名,一般和所实现的功能有关;
  6. 例如:can has get set is load等等
  7. 2. 代码中变量名不能和函数名一样重复
  8. 3.()里面无值是无参函数

调用

🔥🔥🔥 函数名()
声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数
函数代码调用:

  • 运行流程:函数()—-》函数体执行,完毕后结束
  • 函数特点:
    1. 可以多次调用
    2. 可以在任意时刻调用(当然前提是已经声明好了)

扩展:函数声明的时机,是在 js 刚进入执行环境的时候 (函数声明会提前)
函数声明存在提升
(声明函数不是运行到这一行了才声明,不像let 变量一样)

例子

<script>
debugger  //断点
    //声明函数 
    function sayHi() {
      alert("你好")      🚀🚀🚀//第二步  函数体运行
    }                    🚀🚀//第三步  函数体结束
    sayHi()              🚀//运行第一步 跳过函数声明, 调用函数;
    sayHi()             //可以多次调用,每调用一次函数,函数体就运行一次
  </script> //最后 结束

封装

把代码封装成函数进行调用

   // 封装一个函数,计算1-100之间所有数的和
    getTotal();
    function getTotal() {
      let total = 0;
      for (let i = 1; i <= 100; i++) {
        total += i;
      }
      console.log(total);
    }
//封装九九乘法表,调用三次
<script>
    debugger
    numAc()
    function numAc() {
        //遍历很重要!!!
      for (let i = 1; i <= 9; i++) {
        for (let j = 1; j <= i; j++) {
          document.write(`${j}*${i}=${j * i}&nbsp&nbsp&nbsp&nbsp`)
        }
        document.write('<br>')
      }
    }
    numAc()
    numAc()
  </script>

传参

若函数完成功能需要调用者传入数据,那么就需要用有参数的函数
这样可以极大提高函数的灵活性
传递的不是容器; 而是一个值 【按值传递】

声明语法

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

参数列表:1. 传入数据列表
         2. 声明要传入几个数据,可以传1个,或者多个,看需求
         3. 多个数据用逗号隔开

调用

相当于实参为形参赋值
任何类型的数据都可以作为参数传递

函数名(传递的参数列表)

调用参数的时候,需要传递参数,参数是一一对应的


🔥注意:1. 函数功能定义参数的个数,定义参数干什么?

       2. 传递了参数,函数体就要根据参数进行业务处理

函数 - 图1

形参

方法声明的时候设置的参数叫形参,形式参数

特点注意:

  1. 不要使用let 定义
  2. 形参相当于方法的局部变量,只有在方法中可以使用
  3. 方法的形参在没有调用方法之前,只是一个形式的占位,需要接收传递的数据,它才是真正的变量

    实参

    真正存在的值,实际的参数,实参是由调用者提供的,调用的时候是实参
    开发中尽量形参和实参个数一致
    😊💥😊
    形参和实参的三对应:1. 个数对应
    2. 顺序对应————-Js多强调
    3. 类型对应
    以上写错不报错,特别注意

    例子
    <script>
    
     // 总流程:
     // 1. JS代码从上到下解析; 刚进入当前作用域时;
         扫描有没函数声明,有则先声明(函数声明提升)
    
     // 2. 声明函数的同时,如果发现函数有形参;
          相当于在函数内部let 了这些形参变量;
    
     // 3. 函数执行,如果有传递实参; 
          相当于在内部,优先执行了变量(形参)的赋值;
    
     // 4. 之后再继续执行函数体;
    
     // 形参: 声明函数的时候,在小括号内部定义的变量
     function getSum(num1, num2) {
       // 相当于:执行了赋值操作变量声明
       // let num1; // 默认值为undefined
       // let num2;
       // 相当于:执行了赋值操作
       // num1 = 10
       // num2 = 20
       console.log(num1 + num2);
     }
     // 实参: 函数执行的时候,在小括号内部传递的数据
     getSum(10, 20);
    </script>
    
    <script>
     function getSum(x, y) {
       // 逻辑中断:  逻辑或的技巧: 取默认值
       // 1. 当 y 没传实参时, 默认值为 undefined
           如果都没有没传实参的情况下,默认值还为 undefined
       // 2. undefined || 0 ;   前为逻辑假,返回后面的值 0
       // 3. 相当于 y = 0 ; 设置了默认值
    
       x = x || 0;  // 1 || 0
       console.log(x) //1
    
       y = y || 0;  //undefined || 0
       console.log(y) //0
       document.write(x + y);
     }
     getSum(1);
    </script>
    <script>
     let score = [231, 4, 235, 3, 6, 456, 5, 7];
     let score2 = [1, 44, 235, 32, 6, 124, 512, 7];
     let score3 = [155, 44, 28, 32, 62, 2, 512, 57];
     // : 封装一个求和函数
     // : 传递过去的参数是一个数组
     // : 函数内部遍历数组求和
     getSum(score)
     getSum(score2)
     getSum(score3)
     function getSum(arr) {
       let sum = 0
       for (let i = 0; i < arr.length; i++) {
         sum += arr[i]
       }
       console.log(sum)
     }
     // document.write(sum)
    </script>
    

    返回值

    有返回值的函数:当调用某个函数,这个函数会返回一个结果出来
    JS底部内置的有,可以直接使用:可看上回笔记
    prompt();parseInt();等等
    有些函数并没有返回值:alert()
    根据需要来判断是否需要返回值

    return

    当函数需要返回数据出去时,用return关键字
    函数内部,使用了 return,返回了值之后如何处理结果,就由外界自己定了

    语法

    return 数据

    注意点

  • 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  • 函数内部只能运行到 1 次 return,所以 return 后面的数据不要换行写
  • return会立即结束当前函数, 换句话说就是 return 之后的代码不会再被执行
  • 函数可以没有 return,这种情况函数默认的返回值为 undefined
  • return后面不接数据或者函数内不写return,函数的返回值为undefined
  • 函数可以有多个函数,函数位置不同,功能不同;
  • 如果是返回值一定要写在最后;如果是终止函数,另说

    <script>
      // 使用返回值的 注意事项:
      debugger;
      function getSum(x, y) {
        // 3. return不要换行写; 如果换行写,相当于 return;了,返回 undefined
        return;
        // x + y;
        // 2. return 之后的代码,不会执行
        // console.log(123);
      }
      // 1. 函数内部的值,外部访问不到(函数内部只能通过return,返回内部的值)
      // console.log(x);
    
      console.log(getSum(1, 2));
        // 4. 任何函数都有返回值,如果没有return,这种情况默认返回undefined
    </script>
    

    一个函数只能放回一个变量,如果多个值需要返回,可以将多个值包装到数组中,返回到一个数组

    作用域

    可用性的代码范围就是这个名字的作用域
    作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局作用域 局部作用域 块级作用域
全局有效 局部有效 {}内有效
整个 script 标签内部或者多个 js 文件 作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。 指 { } ,一个变量从定义开始,到它所在的 {} 中的 } 结束,例如if语句和for语句里面的{ }等

变量作用域特殊点:

写法规范一般:全局变量 首字母大写;其他小驼峰
如果函数内部或者块级作用域内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
其实是给 window对象,增加了一个属性;

函数内部的形参可以看做是局部变量,所以形参相当于函数内部定义的局部变量,只有在函数内部可以使用。

for(let i = 0;i<3;i++){}; for循环声明的循环参数,也可以看成是局部变量;

全局变量 局部变量 块级变量
函数外部let
的变量(全局作用域内)
函数内部let
的变量(函数作用域中)
{}内部的let变量
全局变量在变量定义之后区域可以访问和修改 局部变量只能在当前函数内部访问和修改 let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问

作用域链

  1. 只要有代码,就至少有一个作用域
  2. 多个嵌套的作用域,形成了一层层包裹关系,构成了作用域链;
  3. 作用域链:采取就近原则的方式来查找变量最终的值;
    2.1 查找变量的过程,就是沿着作用域链从底到高查找的过程
    2.2 函数内部可以访问函数外部的成员,在一个函数里面定义另外一个函数,当函数中需要使用一个变量的时候,先查找自己是否有这个变量;如果没有,找外部函数,如果还没有继续向外查找,直至全局作用域;如果全局也没有,报错!!!

  4. 作用域链顶层对象: window;
    也就是说,window才是真正的顶级对象,包含了万物;

    注意点:

    变量没有声明,直接赋值;其实就是访问到了顶层window;
    并且给window增加了一个属性; window.newVar = 123;
    有一些属性,比如name,直接写不报错;是因为它是 window的一个属性

    匿名函数

    函数分类

    具名函数

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

匿名函数

function(){}

不能单独存在,要么是值,要不是参数,做参数回调函数==

匿名函数写法

将匿名函数作为一个值赋值给一个变量,并且可以通过变量名称进行函数调用;
这个声明形式称为函数表达式

语法:

let fn = function(){
//函数体
}

调用:

fn() //函数名()

其中函数的形参和实参使用跟具名函数一样

声明函数的两种方式

  1. 函数声明 function name(){}; 存在声明提升,有赋值
  2. 函数表达式: let name = function(){}; 变量声明提升,但是没赋值
  <script>
      // 匿名函数总结(了解):
      // 1. 作为值传递
      // 2. 作为实参传递
      //通过function声明的函数是全局函数,全局不释放,会造成全局污染

      // 2. 体验操作页面元素
      let btn = document.querySelector("button");
      // 匿名函数作为值 赋值给一个 对象的属性
      btn.onclick = function () {
        alert("我是匿名函数");
      };

      // 1. 体验 匿名函数
          函数表达式--不是全局函数,用完销毁,不会造成全局污染
      let fn = function () {
        console.log(123);
      };
      debugger;
      // 两部分构成
      fn();
    </script>

web API 使用

应用场景

匿名函数可以用于:立即执行函数
避免全局变量之间的污染
例如Jquery等库;一般最外层都会裹上匿名函数;防止全局变量污染
回调函数—》有异步的地方一般就会出现回调函数—》JS是异步的

立即执行函数

自调用函数

语法:

//  注意  小括号使用
//方法一
(function() { console.log(11) }) ();
//沙箱;💥💥💥前面要有 ; 断开隔开,否则报错--不是个函数。。。

//方法二
(function() { console.log(11) } ());

//不需要额外调用,立刻执行,
//其实本质上已经调用了
💥注意: 多个立即执行函数要用 ; 隔开,要不然会报错

软件工具:

uTools工具 看个人使用习惯
Snipaste_2022-05-23_08-28-40.png