问题
1. 什么是闭包? 有什么作用?
- 概念:闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。所以,在本职上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
- 作用:一是可以读取函数内部的变量;二是让变量的值始终保持在内存中。
2. setTimeout 0 有什么作用?
- 实现javascript的异步; 正常情况下javascript都是按照顺序执行,但可以利用 setTimeout延时0ms(setTimeout 0 )来让该语句后面的语句执行完再执行语句本身。
- 在事件中,setTimeout会在其完成当前任何延宕事件的事件处理器的执行,以及完成文档当前状态更新后,告诉浏览器去启用 setTimeout内注册的函数。
代码题
1. 下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法
var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i; }; } console.log( fnArr[3]() ); //
方法一:立即执行函数中利用临时变量保存i值
var fnArr = []; for (var i = 0; i < 10; i ++) { (function(n){ var n = i; fnArr[i] = function(){ return n; }; })() } console.log( fnArr[3]() );
方法二:赋值给立即执行函数,外部需要传递参数
var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(i){ return function(){ return i; } })(i); } console.log( fnArr[3]() );
方法三:赋值给立即执行函数,声明一个临时变量,外部不需要传递参数
var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(n){ var n = i; return function(){ return n; } })() } console.log( fnArr[3]() );
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
代码如下:
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 } }());
输出结果:
3. 写一个函数使用setTimeout模拟setInterval的功能
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。setInterval函数的用法与setTimeout完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。
如果用setTimeout实现setInerval的功能,就需要在执行的程序中再定时调用自己才行。
代码如下:
`
var i = 0;
function intv( ) {
setTimeout (function( ) {
console.log(++i);
intv( );
}, 1000)
}
intv( );`
输出结果:
4. 写一个函数,计算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) }
5. 下面这段代码输出结果是? 为什么?
var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0); var a ; console.log(a); a = 3; console.log(a);
分析:
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
输出结果为1,3,2,setTimeout函数必须要等到当前脚本的同步任务和“任务列队”中已有的事件全部处理完成之后,才会执行setTimeout指定的任务,所以最后输出2。
6. 下面这段代码输出结果是? 为什么?
var flag = true; setTimeout(function(){ flag = false; },0) while(flag){} console.log(flag);
没有输出。因为setTimeout是在执行完其他代码之后再执行,所以在执行完第一句之后,就到了下面的while循环,而while判断为真,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); }
方法二:
for(var i = 0;i<5;i++){ setTimeout((function(n){ return function() { return console.log('delayer:' + n ); } }(i)),0) console.log(i); }
本教程版权归饥人谷和作者所有,转载须说明来源。