1.什么是闭包?有什么作用?
闭包是指在 JavaScript 中,内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(执行结束被释放)了之后。
- 闭包是指将函数外部的变量保存在函数内部,以备函数执行的时候可以访问,即使这个外部变量本身被释放了,在这个内部函数执行的时候依然可以访问,凡是实现这种功能的都可以称为闭包。闭包最明显的特征是在一个函数中return出一个函数,通过这个函数访问外部的变量,是实现封装的基础。
- 维持了一个独立的数据空间,使得程序可以在函数外部访问局部变量,一般用于模块封装,但是闭包会带来内存泄漏的危险。
2.setTimeout 0 有什么作用
setTimeout 0是将函数的执行顺序移到代码的最后立即执行,即其他代码执行完后立即执行。
代码
- 下面的代码输出多少?修改代码让fnArri 输出 i。使用两种以上的方法
1
2
3
4
5
6
7var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() ); //10
使用闭包实现:1
2
3
4
5
6
7
8
9
10var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] =(function(i){
return function(){
return i;
}
}(i));
}
console.log( fnArr[4]() ); //4
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] =(function(){
var n=i;
return function(){
return n;
}
}());
}
console.log( fnArr[3]() ); //3
使用闭包封装一个汽车对象,可以通过如下方式获取汽车状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48var Car = (function () {
var speed;
function setSpeed(s){
speed = s;
}
function getSpeed () {
console.log(speed);
}
function accelerate () {
speed += 10;
}
function decelerate () {
speed -= 10;
if(speed<0){
speed = 0;
}
}
function getStatus () {
if(speed>0){
console.log("running");
}else{
console.log("stop");
}
}
return {
setSpeed:setSpeed,
getSpeed:getSpeed,
accelerate:accelerate,
decelerate:decelerate,
getStatus:getStatus
}
})();
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';
console.log(Car.speed); //undefined写一个函数使用setTimeout模拟setInterval的功能
1
2
3
4
5
6
7function inter () {
setTimeout(function () {
console.log("每隔一秒输出一次");
inter();
},1000);
}
inter();
1 | setTimeout(function inter () { |
写一个函数,计算setTimeout最小时间粒度
1
2
3
4
5
6
7
8
9
10
11var start = Date.now();
var i=0;
var delayer = setTimeout(function () {
i++;
if(i===1000){
var end = Date.now();
clearTimeout(delayer);
console.log((end-start)/i);
}
setTimeout(arguments.callee, 0);
},0);//4.1ms左右下面这段代码输出结果是? 为什么?
1
2
3
4
5
6
7
8
9var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
输出1,3,2:
- 首先看执行过程var a声明了两次但均被前置,之后执行语句,a=1,setTimeout 0,则会放到代码的的最后去执行,接着执行console.log(a),此时 a=1,所以输出1;
- 执行语句a=3,console.log(a)将其输出为3;
- 代码执行完,立即执行setTimeout 0里面的函数,a=2,由于函数内部没有声明,去全局作用域找并赋值,console.log(a)输出2;
- 下面这段代码输出结果是? 为什么?
1
2
3
4
5
6var flag = true;
setTimeout(function(){
flag = false;
},0)
while(flag){}
console.log(flag);
j结果:死循环,因为setTimeout 0是放到整个代码的最后执行的,所以flag赋值为true后,执行while循环,因为flag=true,所以循环条件一直满足,也就是一直执行while,死循环
- 下面这段代码输出?如何输出delayer: 0, delayer:1…(使用闭包来实现)
1
2
3
4
5
6for(var i=0;i<5;i++){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
}
0,1,2,3,4, 5个delayer:5
闭包实现:1
2
3
4
5
6
7
8for(var i=0;i<5;i++){
(function (i) {
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
})(i);
console.log(i);
}