闭包和定时器

setTimeout的语法

更新于2017年4月9号

setTimeout(func,time,params)  //一定time后,传入回调函数的参数params,并调用回调函数
setTimeout(func,time)  // 一定time后调用回调函数
setTimeout(code,time) //一定time后调用代码块(不推荐)

问题

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

闭包:一个变量,一个函数(环境),函数内部可以访问到这个变量就是一个闭包。
闭包的作用:1.可以访问函数内部的变量。2. 使变量可以一直保存在内存中。

2.setTimeout 0有什么作用

由于js的渲染机制是单线程序,无法同时执行多个不同的代码,当一个代码正在执行的时候,其他的代码都需要等待,直到正在运行的代码运行完后,才能运行下个等待的代码。所以一次点击事件,setTimeout,ajax异步请求都不是立刻的执行,而是立刻的排队。一旦线层空闲下来,就立刻执行。所以setTimeout 0不会立刻执行,而是排队等已经在执行的执行完,然后执行。

var c= 0 ;
function play(){
  console.log(c)
}
function add(){
  setTimeout(()=>{c+=1},100)
}

add()
play()
// 输出0
console.log(1)
setTimeout(function(){console.log},0)
console.log(3)
执行顺序
console.log('start')
setTimeout(function (){console.log("hello,200ms")},200)
setTimeout(function (){console.log("hello,100ms")},100)
console.log('end')
//start
//end
//hello,100ms
//hello,200ms
console.log('start')
setTimeout(function (){console.log("hello,200ms")},200)
for(var i=0;i<10000;i++){console.log(1)}
setTimeout(function (){console.log("hello,100ms")},100)
console.log('end')
//start
//10000个1
//end
//hello,200ms
//hello,100ms

setTimeout会被异步到另一个内存中,当程序流执行完成后,如果时间程序流运行完,setTimeout的时间还没有到,就谁最短谁就呈现然后再执行setTimeout的程序。

代码题

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

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

修改后

  1. 通过闭包来实现获取i
    var fnArr=[];
    for(var i=0;i<10;i++){
        fnArr[i]=function (n){
            var num =n;
            return function () {
                return num;
            }
        }(i)}
        console.log(fnArr[5]())

2.得不到i,无非就是你手速慢了,当你运行函数的时候,i的值就已经等于10了, 通过立即执行函数来获取i

    //第二种方法
    var fnArr=[];
    for(var i=0;i<10;i++){
        fnArr[i]=(function(){
            var obj ={};
            obj.i=i;
            return  obj.i
        })()
    }

    var fnArr=[];
    for(var i=0;i<10;i++) {
        (function(n){
            var num= n;
            fnArr[n] = function(){
                return num;
            }
        })(i)
    }

2. 使用闭包封装一个汽车对象

    var Car = (function () {
        var obj = new Object();
        obj.speed=0;
        obj.setSpeed=function (s) {
           obj.speed=obj.speed+s;
           return;
        }
        obj.getSpeed=function () {
            return obj.setSpeed;
        }
        obj.accelerate=function () {
           obj.speed=obj.speed+10;
           return
        }
        obj.decelerate =function (){
            obj.speed=obj.speed-10;
        }
        obj.getStatus =function (){
            if(obj.speed===0){
                return 'stop'
            }
            else{
                return 'running'
            }
        }
        return obj;
    })()

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

    setTimeout(function sayHello(){
        console.log("hello");
        setTimeout(sayHello,1000);
    },1000)

拓展

具名函数,全局函数,局部函数的区别

  1. 具名函数 :setTimeout里面的函数就是具名函数,只能在setTimeout里面使用,如果在外部调用会报错。


    具名函数
  2. 全局函数:在任何的作用域都可以使用,就像window自带的方法和属性
  3. 局部函数:只能在其父元素的函数作用域中使用(闭包除外)
    局部函数

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

让setTimeout执行1000次,然后我们除以执行的次数

    function  getMini2() {
        var now = Date.now();
        console.log(now);
        var i =0;
        var clock=setTimeout(function () {
           i++;
           if(i===1000){
               clearTimeout(clock);
               var fnow = Date.now();
               console.log((fnow-now)/i);
           }
           setTimeout(arguments.callee,0);
        },0)
    }

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

知识点1.变量的声明前置。2.setTimeout的异步加载处理
由于setTimeout,所以匿名函数中的内容会在程序加载完成的空闲时间去执行,所以会被放到最后一个console.log(a)后执行。

6.输出结果分析

var flag = true;
setTimeout(function(){
    flag = false;
},0)
while(flag){}
console.log(flag);
//无限死循环,没有任何输出

Javascript引擎(JS引擎)是单线程的,在某一个特定的时间内只能执行一个任务,并阻塞其他任务的执行,也就是说这些任务是串行的。我们可以通过异步处理方法,当主线程在执行的过程中,异步处理的代码会被交到另一个模块去执行,当满足它执行的条件后,会被推到任务执行队列,在主线程全部加载完成,空闲下来后,就会去检查任务队列,执行里面的代码。
所以上面的setTimeout(function(){flag=false},0)会被最后执行,这样while就死循环了

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

for(var i=0;i<5;i++){
    setTimeout(function(){
         console.log('delayer:' + i );
    }, 0);
    console.log(i);
}
//输出
//0,1,2,3,4 delayer: 5(5次)

分析

setTimeout(function(){
         console.log('delayer:' + i );
    }, 0);

上面一个代码块会在for(var i=0;i<5;i++),执行完后再执行,所以得到的i就是5

使用闭包输出delayer:0

    for(var i=0;i<5;i++){
        //我们把i传递到函数中
        (function(n){
            //用一个参数来接受它,然后返回一个函数调用这个参数
            var m = n;
            return setTimeout(function(){
                return console.log('delayer:' + m);
            },0)//通过setTimeout自动让它执行
        })(i)//立即执行它,得到几个函数
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 题目1: 下面的代码输出多少?修改代码让fnArr[i]() 输出 i。使两种以上的方法 题目2: 封装一个汽车对...
    Gia_Mo阅读 500评论 0 0
  • 题目1: 下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法 第一种: 第二种: 题目2: ...
    大大的萝卜阅读 285评论 0 0
  • 问题 一、什么是闭包? 有什么作用? 闭包闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函...
    婷楼沐熙阅读 582评论 0 0
  • 题目1:下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法 作用域链: 法一: 作用域链: ...
    lingfighting阅读 173评论 0 0
  • 什么是闭包? 有什么作用闭包:函数对象可以通过作用域链相互关联,函数体内部的变量可以保存在函数的作用域内。 上述代...
    coolheadedY阅读 727评论 0 0