JavaScript程序的递归、回调函数(八)

IIFE(自执行函数)

IIFEImmediately Invoked function Expression),立即调用的函数表达式。声明这个函数的同时立即调用这个函数。

所谓自执行函数,顾名思义,就是定义以后就立刻执行的函数,一般没有名字,而且只会执行一次。

//以function开头了那就是需要一个名字,它就不是表达式方式声明。
function (){//这里报的错是:函数需要一个名字。
    console.log('foo');
}();

我们常用的就是下面这两种方式:

(function xiaoGuaiGuai(){
        console.log('foo!!!');
    }());
//这种方式是最常用的。
(function(){
    console.log('foo@@@');
})();

小括号的作用:

  • 分组操作符。(将数据分成一组)

    (1+2)*3

  • 函数调用符:前面的东西能够得到一个函数值的时候。

立即调用的函数表达式只能运行一次。原因:确实它还是引用类型,但是没有标识,执行完成之后就被垃圾回收机制回收了。

定义之后马上调用,调用之后马上释放。

即使是两个代码完全相同的IIFE函数,也是不同的执行环境、不同的函数。

IIFE函数本身不会被提升,但是函数内部的代码该提升还是会提升的。

如果要向IIFE中传值那么只需要在函数调用符的地方传入实参:

(function(name){
    console.log(name+'是英俊哥!');
})('图图的爸爸');

用处(了解一下):

  1. 在项目中进行项目的初始化,一进入到程序就对项目进行一系列的初始化,初始化完毕以后就不用了那就释放了。
  2. 框架、模块、库中使用IIFE的也比较多。因为这样可以用来进行项目的初始化并且只暴露需要暴露的模块。

函数的递归调用

函数的使用方式

在这里插入图片描述

  1. 主角始终都是小军军。
  2. 小军军一件事没做完就去做另外一件事了。
  3. 小美女的出现最终实际上是个终止条件(
  4. 当前这件事做完之后就会去做上一次还没做完的事。一直到所有的事情都做完。

同一个函数多次调用,执行环境不同(分配的地址空间不同),每个执行环境中的相同的变量没有关系。

递:进去

归:出来

注意:

  1. 你自己就是这个函数,是你自己调用自己。当自己做完一件现在的事的时候,会去做上次没做完的事。
  2. 递归一定要有一个条件限制,否则会陷入自己调用自己的旋窝中,永不翻身。
  3. 不确定具体调用多少次的情况。

在这里插入图片描述

在这里插入图片描述

例子:

  1. 求1~5的和,用递归。

    编码过程中能少用全局变量就少用全局变量。

    在这里插入图片描述

  2. 计算数组中元素的个数。

    在这里插入图片描述

    判断数组:Array.isArray(变量),是数组返回true,否则返回false

    var arr = [1, [5, 4, 6], 9, [4, 5, [0, 2, [7, 3]]]];
    
        function ARR(arr) {
          var sum = 0;
          for (var i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
              sum += ARR(arr[i]);
            } else {
              sum++;
            }
          }
          return sum;
        }
        console.log(ARR(arr));
    

函数的回调(回调函数)

回调函数的精髓:函数是对象,是值,可以被当作参数传入到函数中 。

学习回调函数需要掌握的知识点:

  • 将一个引用类型赋值给一个变量时,变量存储的是引用类型的地址

    一个引用类型可以有多个名字,一个改变引用类型的值,另外一个的值也改变。

    var a = [];
        a[0] = '苹果';
        var b = a;//a和b的地址指向同一个。
        console.log(b);
    
        function foo(){
        }
        var foo1 = foo;//也是同一个。
    
  • 函数的参数,如果是普通类型传递的是值,引用类型传递的是地址

    function test(arr){//arr=0x123
            arr[arr.length] = '小香蕉';
        }
        var a = ['小苹果'];//0x123
        test(a);//test(0x123)
        console.log(a);//['小苹果', '小香蕉']
    
  • 一个函数本身是值,也是一个对象,可以被当作实参传入到函数中

    在这里插入图片描述

  • 一个函数本身是值,也是一个对象,所以可以被当作返回值返回回来

    function foo(){//0x123
        function bar(){//0x234
            console.log('foo---->bar');
        }
        return bar;//0x234
    }
    var res = foo();//res=0x234
    res();//0x234()
    
什么是回调函数

回调函数被认为是一种高级函数,一种被作为参数传入给另外一个函数(A)的高级函数。回调函数会在A里面被调用被执行。

回调函数的本质是一种模式,是解决问题的一种套路。

回调函数的用处
  • 事件监听和处理。
  • 设置超时和时间间隔。
  • Ajax。
  • 框架中的各种生命周期回调函数。
  • 通用化:代码简洁,易于扩展。
<script>
    //通用函数
    function getNumber(num, fn) {//num=3;fn=0x123
        /*
        i=1 1<=3 true
            fn(1);//false
            console.log(1);
        i=2 2<=3 true
            fn(2);//true
        i=3 3<=3 true
            fn(3);//false
            console.log(3);
        i=4 4<=3 false
        */
        for (var i = 1; i <= num; i++) {
            if (fn(i)) {
                continue;
            }
            console.log(i);
        }
    }

    //规则1:偶数
    function rules1(n) {//0x123
        if (n % 2 == 0) {
            return true;
        } else {
            return false;
        }
    }

    // getNumber(3,rules1);//getNumber(3,rules1)

    //规则2:和4取余为0的都保留
    function rules2(n){
        if (n%4!=0){
            return true;
        }else {
            return false;
        }
    }
    // getNumber(10,rules2);

    //手抄10遍意思一下。
    
    //规则3:将奇数去掉
    getNumber(10,function(n){
        if (n % 2 == 0){
            return false;
        } else{
            return true;
        }
    });
</script>

这个例子你可以看出来将功能提取出来后将各种规则也提取出来,减少耦合、容易扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值