闭包

     for(var i = 0;i < 10;i++){
       }
       console.log(i);

课前准备:上面这个函数的输出结果是10,因为当i == 10的时候,不满足函数循环的条件,退出循环。

正式例题

       function test(){
           var arr = [];
           for(var i = 0;i < 10;i++){
               arr[i] = function (){
                document.write(i+' ');
               }
           }
           return arr;
       }
       var arr = test();
       for(var j = 0; j < 10;j++){
           arr[j]();
       }

解析:此时打印出来的是10个10,10个很容易理解,因为for循环执行了10次,但是,为什么是10呢?为什么不是1,2,3,4,5,6,7,8,9,呢?因为在

 arr[i] = function (){
                console.log(i);
               }

的时候,仅仅是arr[]数组中德项数被赋值为函数,该函数并没有被立刻执行,(如果想立即执行,可以在后面加上括号),在下面for循环执行的时候,i的值已经像最初的引言函数中的那样,i的值已经变成10

解决方案

问题描述:上面的问题是我想输出0,1,2,3,4,5,6,7,8,9,可是现在输出的却是10个10,解决方案目前来看有且仅有一种。

        function test(){
           var arr = [];
           for(var i = 0;i < 10;i++){
               (function(j){    //注意此时的改变
                arr[j] = function (){
                console.log(i);
               }
               }(i))
           }
           return arr;
       }
       var arr = test();
       for(var j = 0; j < 10;j++){
           arr[j]();
       }

解析:立即执行函数会每次执行完之后销毁,每个j与每个立即执行函数function具有一一对应的关系,每个 function (){
console.log(i);
}保存相对应外部立即执行函数的劳动成果,在这里形成了闭包,内部函数被保存到了外部。
思想:利用立即执行函数闭包解决外部闭包

闭包的作用

  1. 实现公有变量(比如说累加器,但是不借助外部变量)
    如果借助于外部变量的实现方式:
   var count = 0 ;
        function test(){
            count++;
            console.log(count);
        }
        test();
        test();
        test();
        test();
        test();
        test();

使用闭包实现:

       function add(){
           var count = 0;
           function a(){
               console.log(++count);
           }
           return a;
        }
        var demo = add();
        demo();
        demo();
  1. 作为缓存(存储结构)
         function test(){
            var food = 'apple';
            var obj = {
                eat: function(){
                    if(food != ''){
                        console.log('i am eating '+ food);
                        food = '';
                    }else{
                        console.log('There is  nothing!')
                    }
                },
                push: function(myfood){
                    food = myfood;
                }
            }
            return obj;
        }
        var person = test();
        person.eat();
        person.eat();
        person.push('banana');
        person.eat();
  1. 可以实现封装,属性私有化。
  2. 模块化开发,防治污染全局变量。
      var test = function(){
            console.log('a');
        }();
        console.log(test);

解析:后面打印test的时候,此时test不代表一个函数,表达式()执行之后,相当于这个样子

              var test;        console.log(test);

所以打印结果是undefined。
只有表达式才能被执行,函数声明不能被执行。

function(){
…代码块
}()

上面代码会报错,声明不能被执行,但是如果在前面加上一个+号或者减号通过隐式类型转化变成表达式就可以执行。

笔试题

     var f = (
            function f(){
                return '1';
            },
            function g(){
                return 1;
            }
        )();
        console.log(typeof f);

能否抽象出来(a++,++a)逗号的运算法则是解决这个题目的关键。

非常有深度的一道题目

        var x = 1;
        if(function f(){}){
            x += typeof f;
        }
        console.log(x);

输出:1undefined

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值