任务20-闭包、定时器

2016-10-26  本文已影响0人  小木子2016

问题

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

2. setTimeout 0 有什么作用?

代码题

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>

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

上一篇下一篇

猜你喜欢

热点阅读