美文网首页
任务20-闭包、定时器

任务20-闭包、定时器

作者: 小木子2016 | 来源:发表于2016-10-26 09:52 被阅读0次

    问题

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

    • 概念:闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。所以,在本职上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
    • 作用:一是可以读取函数内部的变量;二是让变量的值始终保持在内存中。

    2. setTimeout 0 有什么作用?

    • 实现javascript的异步; 正常情况下javascript都是按照顺序执行,但可以利用 setTimeout延时0ms(setTimeout 0 )来让该语句后面的语句执行完再执行语句本身。
    • 在事件中,setTimeout会在其完成当前任何延宕事件的事件处理器的执行,以及完成文档当前状态更新后,告诉浏览器去启用 setTimeout内注册的函数。

    代码题

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

    <pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i; }; } console.log( fnArr[3]() ); //</pre>
    方法一:立即执行函数中利用临时变量保存i值
    <pre>var fnArr = []; for (var i = 0; i < 10; i ++) { (function(n){ var n = i; fnArr[i] = function(){ return n; }; })() } console.log( fnArr[3]() );</pre>

    方法二:赋值给立即执行函数,外部需要传递参数
    <pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(i){ return function(){ return i; } })(i); } console.log( fnArr[3]() );</pre>

    方法三:赋值给立即执行函数,声明一个临时变量,外部不需要传递参数
    <pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(n){ var n = i; return function(){ return n; } })() } console.log( fnArr[3]() );</pre>

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

    <pre>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</pre>

    代码如下:
    <pre>var Car = (function(){ var speed = 0; function setSpeed(n){ speed = n; } function getSpeed(){ console.log(speed); return speed; } function accelerate(){ speed +=10; } function decelerate(){ speed -=10; } function getStatus(){ if (speed>0){ console.log('running') }else{ console.log('stop') } } return { setSpeed:setSpeed, getSpeed:getSpeed, accelerate:accelerate, decelerate:decelerate, getStatus:getStatus } }());</pre>

    输出结果:

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

    setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。
    如果用setTimeout实现setInerval的功能,就需要在执行的程序中再定时调用自己才行。

    代码如下:
    <pre>`
    var i = 0;
    function intv( ) {
    setTimeout (function( ) {
    console.log(++i);
    intv( );
    }, 1000)
    }
    intv( );

    `</pre>

    输出结果:

    4. 写一个函数,计算setTimeout平均[备注:新加]最小时间粒度

    代码如下:
    <pre>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) }</pre>

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

    <pre>var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0); var a ; console.log(a); a = 3; console.log(a);</pre>

    分析:
    <pre>var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0);//最后执行,输出结果为2 var a ;//声明变量a,此时a的值仍为1 console.log(a);//输出结果为1 a = 3;// 给a重新赋值为3 console.log(a);//输出结果为3</pre>

    输出结果为1,3,2,setTimeout函数必须要等到当前脚本的同步任务和“任务列队”中已有的事件全部处理完成之后,才会执行setTimeout指定的任务,所以最后输出2。

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

    <pre>var flag = true; setTimeout(function(){ flag = false; },0) while(flag){} console.log(flag);</pre>

    没有输出。因为setTimeout是在执行完其他代码之后再执行,所以在执行完第一句之后,就到了下面的while循环,而while判断为真,flag为true,为死循环,执行空语句,无输出。

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

    <pre>for(var i=0;i<5;i++){ setTimeout(function(){ console.log('delayer:' + i ); }, 0); console.log(i); }</pre>

    方法一:
    <pre>for(var i = 0;i<5;i++){ (function () { var n = i; setTimeout(function(){ console.log('delayer:' + n ); }, 0); })() console.log(i); }</pre>

    方法二:
    <pre>for(var i = 0;i<5;i++){ setTimeout((function(n){ return function() { return console.log('delayer:' + n ); } }(i)),0) console.log(i); }</pre>

    本教程版权归饥人谷和作者所有,转载须说明来源。

    相关文章

      网友评论

          本文标题:任务20-闭包、定时器

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