闭包

问题

1.什么是闭包? 有什么作用

  • 闭包:指有权访问另一个函数作用域中变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
  • 作用:模仿块级作用域

用作块级作用域的匿名函数语法如下:

 (function( ){
        //这里是块级作用域
 })( );

下面代码中,在for循环外部插入了一个块级作用域,在匿名函数中定义的任何变量,都会在执行结束时被销毁,所以变量i只能在循环中使用。而该块级作用域能够访问变量count,是因为这个匿名函数是一个闭包,能够访问包含作用域的所有变量。

 function outputNumbers(count){
          (function(){
            for (var i=0;i<count;i++){
                console.log(i);
            }
       
       })();

    }
    outputNumbers(6);

2.setTimeout 0 有什么作用

现有的 JavaScript 引擎是单线程处理任务的。它把任务放到队列中,不会同步去执行,必须在完成一个任务后才开始另外一个任务。setTimeout(fn,0)把fn放到运行队列的最后去执行。也就是说,无论setTimeout(fn,0)写在哪,都可以保证在队列的最后执行。js解析器会把setTimeout(fn,0)里的fn压到队列的最后,因为它是异步操作。 其实,这是一个把需要执行的任务从队列中跳脱的技巧。由于setTimeout可以把任务从某个队列中跳脱成为新队列,因而能够得到期望的结果。

console.log(1);
 setTimeout("console.log(2)", 0);
 console.log(3);
// 执行顺序为:1,3,2 

代码题

  //下面的代码输出多少?修改代码让fnArr[i]() 输出 i。使用两种以上的方法
        var fnArr = [];
        for (var i = 0; i < 10; i++) {
            fnArr[i] = function() {
                return i;
            };
        }
        console.log(fnArr[3]()); //输出10

        //方法一:整个立即执行函数被赋值,然后通过外部函数传参
        var fnArr = [];
        for (var i = 0; i < 10; i++) {
            fnArr[i] = (function(num) {
                return function() {
                    return num;
                }
            })(i);
        }
        console.log(fnArr[3]());

        //方法二:整个立即执行函数被赋值,然后用临时变量保存i的值
        var fnArr = [];
        for (var i = 0; i < 10; i++) {
            fnArr[i] = (function() {
                var n = i;
                return function() {
                    return n;
                }
            })();
        }
        console.log(fnArr[3]());

        //方法三:函数内部返回函数传参
        var fnArr = [];
        for (var i = 0; i < 10; i++) {
            fnArr[i] = (function(n) {
                return function() {
                    return n;
                }
            }(i))
        }
        console.log(fnArr[3]());

        //方法四:函数内部返回函数,用临时变量保存i
        var fnArr = [];
        for (var i = 0; i < 10; i++) {
            fnArr[i] = (function() {
                var n = i;
                return function() {
                    return n;
                }
            }())
        }
        console.log(fnArr[3]());
  var Car = function() {
            var v;
            return {
                setSpeed: function(speed) {
                    v = speed;                  
                },
                getSpeed: function() {
                    console.log(v);
                },
                accelerate: function() {
                    v += 10;
                },
                decelerate: function() {
                    v -= 10;
                },
                getStatus: function() {
                    if (v > 0) {
                        console.log('running');
                    } else {
                        console.log('stop');
                    }
                }
            }
        }();
        Car.setSpeed(30);
        Car.getSpeed(); //30
        Car.accelerate();
        Car.getSpeed(); //40;
        Car.decelerate();
        Car.decelerate();
        Car.getSpeed(); //20
        Car.getStatus(); // 'running';
        Car.decelerate();
        Car.decelerate();
        Car.getStatus(); //'stop';
        //Car.speed;  //error
  //写一个函数使用setTimeout模拟setInterval的功能
        var i = 0;
        setTimeout(function() {
            console.log(i++);
            setTimeout(arguments.callee, 1000);
        }, 1000);
        //写一个函数使用setTimeout模拟setInterval的功能
        var i = 0;

        function copyInterval() {
            console.log(i++);
            setTimeout(function() {
                copyInterval();
            }, 1000)
        }
        copyInterval();
    //写一个函数,计算setTimeout平均[备注:新加]最小时间粒度
      function getMini(){
        var i = 0;
        var start = Date.now();
        var clock = setTimeout(function(){
          i++;
          if(i === 1000){
            clearTimeout(clock);
            var end = Date.now();
            console.log((end-start)/i);
          }
          clock = setTimeout(arguments.callee,0)
        },0)
      }
      getMini();

5.下面这段代码输出结果是? 为什么?

        var a = 1;
        setTimeout(function() {
            a = 2;
            console.log(a);
        }, 0);
        var a;
        console.log(a);
        a = 3;
        console.log(a);
       //输出顺序:1 3 2

6.下面这段代码输出结果是? 为什么?

        var flag = true;
        setTimeout(function() {
            flag = false;
        }, 0)
        while (flag) {}
        console.log(flag);
       //setTimeout在代码最后执行,flag一直为true,死循环

7.下面这段代码输出?如何输出delayer: 0, delayer:1...(使用闭包来实现)

for (var i = 0; i < 5; i++) {
            setTimeout(function() {
                console.log('delayer:' + i);
            }, 0);
            console.log(i);
        }
输出结果
for (var i = 0; i < 5; i++) {
            (function() {
                var n = i;
                setTimeout(function() {
                    console.log('delayer:' + n);
                }, 0);
            })()
            console.log(i);
        }
输出结果
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.什么是闭包? 有什么作用 定义:闭包就是嵌套在函数里面的内部函数,并且该内部函数可以访问外部函数中声明的所有局...
    饥人谷区子铭阅读 990评论 0 2
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 5,632评论 16 88
  • 特别说明,为便于查阅,文章转自https://github.com/getify/You-Dont-Know-JS...
    杀破狼real阅读 498评论 0 0
  • 什么是闭包? 有什么作用闭包的形成在高级程序设计3中对于闭包的定义是这样的 有权访问另一个函数作用域中的变量的函数...
    老虎爱吃母鸡阅读 114评论 0 0
  • 为人处事的基本原则如下: 1.为人谦逊。即便是比别人高,比别人强,别人有求于己,也保持一个基本的礼貌和谦逊,推己及...
    橙君阅读 1,100评论 0 1