闭包

作者: 小周师傅 | 来源:发表于2016-08-29 20:29 被阅读0次

问题

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);
        }
输出结果

相关文章

  • swift-闭包

    闭包 闭包定义 闭包简化 - 尾随闭包 闭包参数 闭包返回值 闭包的循环引用

  • 闭包,闭包,闭包

    1、这家伙到底是什么? 网上关于这个的讨论的太多了太多了,有各种的举例子,但是大部分还在寻找这个答案的小伙伴对于变...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • Day7 闭包(Closures)

    本页包含内容:• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包 1、闭包表达式 闭包...

  • Python闭包

    闭包 = 环境变量 + 函数 调用闭包内部的环境变量 闭包的经典误区 闭包与非闭包实现人类走路 非闭包 闭包

  • 闭包(closure)

    ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...

  • swift- 闭包一

    /*• 闭包表达式• 尾随闭包• 值捕获• 闭包是引用类型• 逃逸闭包• 自动闭包*/

  • (9) python之闭包

    闭包闭包 = 函数 + 环境变量(函数定义的时候) 一个最简单的闭包 闭包不受外部变量影响 非闭包 闭包 闭包 只...

  • Swift-进阶 :闭包(二)逃逸闭包 & 非逃逸闭包

    本文主要分析逃逸闭包 、非逃逸闭包、自动闭包 逃逸闭包 & 非逃逸闭包 逃逸闭包定义 当闭包作为一个实际参数传递给...

  • javascript闭包详解

    跟我念 bi 闭 bao包 ,闭包的闭,闭包的包。。 闭包的简介 在计算机科学中,闭包(英语:Closure),又...

网友评论

      本文标题:闭包

      本文链接:https://www.haomeiwen.com/subject/adwxettx.html