问题
1.什么是闭包? 有什么作用
- 闭包:指有权访问另一个函数作用域中变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
- 作用:模仿块级作用域
用作块级作用域的匿名函数语法如下:
(function( ){
//这里是块级作用域
})( );
下面代码中,在for循环外部插入了一个块级作用域,在匿名函数中定义的任何变量,都会在执行结束时被销毁,所以变量i只能在循环中使用。而该块级作用域能够访问变量count,是因为这个匿名函数是一个闭包,能够访问包含作用域的所有变量。
function outputNumbers(count){
(function(){
for (var i=0;i<count;i++){
console.log(i);
}
})();
}
outputNumbers(6);
2.setTimeout 0 有什么作用
现有的 JavaScript 引擎是单线程处理任务的。它把任务放到队列中,不会同步去执行,必须在完成一个任务后才开始另外一个任务。setTimeout(fn,0)把fn放到运行队列的最后去执行。也就是说,无论setTimeout(fn,0)写在哪,都可以保证在队列的最后执行。js解析器会把setTimeout(fn,0)里的fn压到队列的最后,因为它是异步操作。 其实,这是一个把需要执行的任务从队列中跳脱的技巧。由于setTimeout可以把任务从某个队列中跳脱成为新队列,因而能够得到期望的结果。
console.log(1);
setTimeout("console.log(2)", 0);
console.log(3);
// 执行顺序为:1,3,2
代码题
//下面的代码输出多少?修改代码让fnArr[i]() 输出 i。使用两种以上的方法
var fnArr = [];
for (var i = 0; i < 10; i++) {
fnArr[i] = function() {
return i;
};
}
console.log(fnArr[3]()); //输出10
//方法一:整个立即执行函数被赋值,然后通过外部函数传参
var fnArr = [];
for (var i = 0; i < 10; i++) {
fnArr[i] = (function(num) {
return function() {
return num;
}
})(i);
}
console.log(fnArr[3]());
//方法二:整个立即执行函数被赋值,然后用临时变量保存i的值
var fnArr = [];
for (var i = 0; i < 10; i++) {
fnArr[i] = (function() {
var n = i;
return function() {
return n;
}
})();
}
console.log(fnArr[3]());
//方法三:函数内部返回函数传参
var fnArr = [];
for (var i = 0; i < 10; i++) {
fnArr[i] = (function(n) {
return function() {
return n;
}
}(i))
}
console.log(fnArr[3]());
//方法四:函数内部返回函数,用临时变量保存i
var fnArr = [];
for (var i = 0; i < 10; i++) {
fnArr[i] = (function() {
var n = i;
return function() {
return n;
}
}())
}
console.log(fnArr[3]());
var Car = function() {
var v;
return {
setSpeed: function(speed) {
v = speed;
},
getSpeed: function() {
console.log(v);
},
accelerate: function() {
v += 10;
},
decelerate: function() {
v -= 10;
},
getStatus: function() {
if (v > 0) {
console.log('running');
} else {
console.log('stop');
}
}
}
}();
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
//写一个函数使用setTimeout模拟setInterval的功能
var i = 0;
setTimeout(function() {
console.log(i++);
setTimeout(arguments.callee, 1000);
}, 1000);
//写一个函数使用setTimeout模拟setInterval的功能
var i = 0;
function copyInterval() {
console.log(i++);
setTimeout(function() {
copyInterval();
}, 1000)
}
copyInterval();
//写一个函数,计算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)
}
getMini();
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
6.下面这段代码输出结果是? 为什么?
var flag = true;
setTimeout(function() {
flag = false;
}, 0)
while (flag) {}
console.log(flag);
//setTimeout在代码最后执行,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);
}
输出结果