美文网首页
闭包、定时器

闭包、定时器

作者: StarLikeRain | 来源:发表于2016-07-28 22:23 被阅读37次

    问题

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

    MDN:闭包是指能够访问自由变量的函数(变量在本地使用,但在闭包中定义)。换句话说,定义在闭包中的函数可以“记忆”它被创建时候的环境。

            <script type="text/javascript">  
                var i = 23333;
                function f(){
                    
                    function g(){
                        i = 502;
                    }
                    return g;
                }
                var func = f();
                func();
             //闭包的主要思想,这样函数内部的局部变量就会一直保留下来,这样外部作用域下访问函数局部变量,好像内部变量被拉到了台面上,可以被外部全局访问,
            </script>
    

    →自己的理解就是弄一个即时运行的函数,里面再套一个函数,外面的即时运行的函数等同于给出了一个停留空间,让内部的函数可以每次都运行出每个步骤的结果。(我的表达很混乱)

    1. setTimeout 0 有什么作用
      setTimeout(function(){
           //do         
      },0)
    

    setTimeout 0;是会以0毫秒的延迟来调用这个setTimeout(),虽然这样,但是这个函数也是不会立即执行,反而会吧这个函数放到队列后面,等到前面的事件处理完毕后再运行。这是一种异步执行。

    代码题

    1.下面的代码输出多少?修改代码让 fnArr[i]() 输出 i。使用两种以上的方法

                var fnArr = [];
                for(var i = 0; i < 10; i++) {
                    fnArr[i] = function() {
                        return i;
                    };
                }
                console.log(fnArr[3]()); //一直10
    

    //答

            <script type="text/javascript">
                var fnArr = [];
                for(var i = 0; i < 10; i++) {
                    (function(n) {
                        fnArr[i] = function() {
                            return n;
                        };
                    })(i);
    
                }
                console.log(fnArr[3]()); //3
                            //用外面一层封装一个即时运行函数的方法
            </script>
    
            <script type="text/javascript">
                var fnArr = [];
                for(var i = 0; i < 10; i++) {
                    
                        fnArr[i] = (function(n) {
                            return function(){
                                return n;
                            };
                        })(i);
                    
                }
                console.log(fnArr[3]()); //3
                                   //直接把变量传递到内部的函数子函数,形成闭包
            </script>
    

    2.使用闭包封装一个汽车对象,可以通过如下方式获取汽车状态

                var Car = //todo;
                    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
    

    //答

            <script type="text/javascript">
                var Car = (function() {
                    var speed = 0;
    
                    function setSpeed(i) {
                        speed = i;
                    }
    
                    function getSpeed() {
                        return speed;
                    }
    
                    function accelerate() {
                        speed += 10;
                    }
    
                    function decelerate() {
                        speed -= 10;
                    }
    
                    function getStatus() {
                        if(speed > 0) {
                            return "running";
                        } else {
                            return "stop";
                        }
                    }
                    return {
                        'setSpeed': setSpeed,
                        'getSpeed': getSpeed,
                        'accelerate': accelerate,
                        'decelerate': decelerate,
                        'getStatus': getStatus,
                        'speed': 'error'
                    };
                }());
    
                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
            </script>
    

    3.写一个函数使用setTimeout模拟setInterval的功能

            <script type="text/javascript">
                var i = 0;
                var clock = setTimeout(function(){
                    setTimeout(arguments.callee,1000);//自己调用自己,这里的1000是自己调用自己的时间间隔,同setInterval
                    console.log(i++);
                },0);
            </script>
    

    4.写一个函数,计算setTimeout最小时间粒度

            <script type="text/javascript">
                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)
                }
            </script>
    

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

            <script type="text/javascript">
                var a = 1;
                setTimeout(function() {
                    a = 2;
                    console.log(a);
                }, 0);
                var a;
                console.log(a);
                a = 3;
                console.log(a);
                //将上面的代码根据运行优先级调整顺序后
                var a;
                a = 1;
                console.log(a);
                a = 3;
                console.log(a);
                setTimeout(function() {
                    a = 2;
                    console.log(a);
                }, 0);
                //setTimeout如果延迟设置为0,那么它的优先级会拉倒最后面........
            </script>
    
    

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

                var flag = true;
                setTimeout(function(){
                    flag = false;
                },0)
                while(flag){}
                console.log(flag);
    //没有输出,因为setTimeout 0使得setTimeout的优先级是最后的,while判断被提前,while为true所以一直会循环输出空语句,就是木有输出啦~
    

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

                for(var i = 0; i < 5; i++) {
                    setTimeout(function() {
                        console.log('delayer:' + i);
                    }, 0);
                    console.log(i);
                }
    //上面的代码因为优先执行for语句的时候i早就等于5了,再setTimeout迟了。之前的1234没有保留下来。
    //下面是实现的代码
            <script type="text/javascript">
                for(var i = 0; i < 5; i++) {
                    setTimeout((function(n){
                        return function(){console.log('delayer'+ n)}
                    }(i)),0);
                    console.log(i);
                }
            </script>
    

    相关文章

      网友评论

          本文标题:闭包、定时器

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