zoukankan      html  css  js  c++  java
  • JS 函数 声明函数 函数三要素 箭头函数 回调函数

    函数

      可以实现一定功能的一段代码的封装。

    注:函数创建过后,在内存堆中以一段字符串文本储存,不执行时不会产生任何作用,就单单是存了一段字符串。

    创建函数

      1、字面量(声明式,推荐)
     
          关键字  标识符  小括号  {函数体}
     
        例:
    function F65(){
        console.log(`我是一个函数F65`);
     }

       

      2、表达式(匿名函数表达式)
     
          关键字  标识符 = function ()  {函数体}
        例:
    let F66 = function () {
        console.log(`我是一个函数F66`);
    }
    let F66 = function F67() {
        console.log(`我是一个函数F66`);
    }
    F66();//我是一个函数F66
    console.log(F66.name);//F67
    console.log(F66);//[Function: F67]
    //F67();//报错  F67 is not defined
    //这个情况有点奇葩
     function F67() {
                console.log(`我是一个函数F67`);
            }
      F67();//我是一个函数F67
    //意味着,前面并没有声明变量 F67,前面的F67只单单作为函数的一个name,但是调用时却必须使用F66作为函数名,有点扯
     
      3、构造函数
     
            关键字  标识符 = new Function ();
        例:
    let F68= new Function(
        "console.log(123)"
    );

    注:内存栈  F68:函数的引用;

      内存堆  函数:"console.log(123)",就是个字符串。

     

    函数三要素

      一、函数名

        函数名取名一般要求是动词或动宾格式,望文知意,其他的和变量标识符一样,并且也会和变量名冲突。

      

      二、参数

          形参:创建函数时,添加的参数
          实参:调用函数时,添加的参数
    注:形参会有初始值:undefined。
     
         调用函数时,实参传给形参的过程相当于:
            let 形参 = 实参;
         有几个参数,就对应几个let。
     
         当形参与实参个数不同,在传统开发语言中,个数不同会报错,即不执行。JS不会:
      
              形参个数大于实参个数  多的形参,值为undefined
      
              实参个数大于形参个数  多的实参,不使用
     
      扩展:
          1、在最后添加一个扩展运算的变量(获取多的实参) 数组
           必须写在最后一个形参位置(尾形参,写在前面会报错),且只能有一个
      
          2、arguments获取所有实参的内容(类数组)
      
            类数组:
              1、可以用下标取值arguments[0]
              2、可以用length获取长度(个数)
              3、但不能数组的方法,例push()会报错
      
      注:函数名.length取的是形参个数(不包含扩展运算符的标识符)。
    function F65(a,b,c,...d){
    
        console.log(a,b,c);//A B C
        console.log(d);//[ 'D', 'E', 'F', 'G', 'H' ]
        console.log(F65.length);//3
        console.log(F65.arguments);//键值对的实参
        console.log(F65.arguments[0]);//A
    }
    F65("A","B","C","D","E","F","G","H");
    function f65(x,y,z,i){
         console.log(arguments[0]);//1
         x=2;
         console.log(arguments[0]);//2
         arguments[0]=5;
         console.log(x);//5
         //形参发生值的改变,相对应的arguments也会发生改变
         //arguments发生值的改变,相对应的形参不会发生改变
         console.log(i);//un
         i=2;
         console.log(i);//2
         console.log(arguments[3]);//un
         //当形参比实参多时,对多的形参进行赋值;
         //相对应的arguments不改变(即无效,也就是打印undefined)
     }
     f65(1,2,3);

    注: 函数名.arguments 和直接 arguments 是不一样的,其实一般都是直接用 arguments。

      参数解构

    function fn(a,b,{c,d}){
        //相当于
        let a=参数1;
        let b=参数2;
        let {c,d}=参数3;
    }
    //意味着参数3传的是一个对象
    //默认值 {c,d=12}={}    {}是参数默认值,d=12是解构默认值

      三、返回值:return

        
        每个函数必须有return,如果没有添加return语句,计算机会自动在函数的最后一行补一个return,返回值为undefined。
        返回函数的结果(常量、变量、公式、表达式),同时终止函数,即不会执行return后面的代码。

     参数的默认值

      函数的形参在书写时可以直接赋值,(不赋值也会有:undefined),函数被调用时,如果形参有对应的实参,就用实参的值,没有就用默认值。

      给形参传值:undefined,函数也会使用该形参的默认值(不一定是undefined),

      .length获取形参个数时,有赋值默认值的形参不会计入个数,如果赋值默认值的形参写在第一个,长度会为0。

      因此,推荐把需要赋值默认值的形参写到最后。

     ES6 箭头函数

        

            x=> num2.has(x)    大多数时候就这个模板,函数返回表达式(num2.has(x))的结果
     

      一般有以下特点:

            1、可以省略 书写 function

            2、如果只有一个形参,可以不打小括号

            3、如果只有一条执行语句,可以不打大括号

            4、只有一条执行语句,并且需要返回这条语句的结果,可以不用写return

            5、不可以使用arguments

            6、不会把自己的this绑定到函数上

            7、不可以用作构造函数

      多数时候使用箭头函数只有一条语句,就是为了简洁方便:

    let num1 = new Set([1, 2, 3, 4]);
    let num2 = new Set([3, 4, 5, 6]);
    // 并集
    let union = new Set([...num1,...num2]);
    console.log(union);//Set { 1, 2, 3, 4, 5, 6 }
    //交集
    let intersect = new Set(
        [...num1].filter(x=> num2.has(x)));
    console.log(intersect); //Set { 3, 4 }
    //差集
    let difference = new Set(
        [...num1].filter(x => !num2.has(x)));
    console.log(difference); //Set { 1, 2 }

    回调函数

       把一个函数A,当参数传递给另一个函数B进行调用,函数A就是回调函数。

        把箭头函数当做回调函数用的最多。

      常用的回调函数

        

    //数组的排序
    let arr = [1, 3, 7, 6, 9, 4, 6, 2];
    let arr1 = arr.sort(
        function (a,b){
            // return b-a;
            return a-b;
        }
    )
    console.log(arr1);
    
    console.log(arr.sort((a, b) => a - b)); //升序
    console.log(arr.sort((a, b) => b - a)); //降序

      回调函数用的非常多,相当重要。

    arr.every(
        function(index){
            return index%2==0;
        }
    )//以下为简写
    // every  数组中每个值都满足条件才返回true
    console.log(arr.every(index => index % 2 == 0)); //false
    //some  数组中有一个条件满足则返回true
    console.log(arr.some(index => index % 2 == 0)); //true
    //filter(过滤) 返回所有满足条件的值
    console.log(arr.filter(index => index % 2 == 0)); //[6,6,4,2]
    //map  返回每个值是否满足条件
    console.log(arr.map(index => index % 2 == 0)); //[ false, false, true, true, true, false, true, false ]

    IIFE

      Immediately Invoked Function Expression

         立即执行函数,创建即调用,调用后即销毁

    注:当立即执行函数中的变量在外面有调用时,变量会不销毁,但是会“隐形”,只有调用它的“人”看得到。

    //一般书写方式
    (function fn(){
        console.log("F65");
    })()
    //也可以
    (function fn(){
        console.log("F65");
    }())
    
    !(function fn(){
        console.log("F65");
    }())
    
    -(function fn(){
        console.log("F65");
    }())
    //主要是为了让这一段代码与其他代码隔开,不会有歧义,形成一个整体

    总结

      函数的表现形式:

        1、声明式

    function fn(){}

        2、表达式

    let fn = function(){}

        3、匿名函数

          不需要起名字的地方,function(){},并不能单独书写,在特定的地方出现,比如作为一个返回值、参数,或者立即执行函数

    function fn(){
       return function(){};          
    };
    function fn(function(){}){};
    (function(){})();

         立即执行函数、回调函数、箭头函数,都可以算作匿名函数的一种情况。

         4、特殊函数、递归函数

        其实就是函数直接或者间接的调用自己。递归一定要给出递归结束条件(递归出口)。

  • 相关阅读:
    CSS 中 Position relative 和 absolute区别
    感受到LDT的好处
    Map数据结构
    break和continue
    vue的ref属性
    css小样式
    搭建vue开发环境
    setTimeout和clearTimeout
    垂直居中
    vertical-align 属性
  • 原文地址:https://www.cnblogs.com/jiayouba/p/11954584.html
Copyright © 2011-2022 走看看