闭包、定时器
2016-07-28 本文已影响37人
StarLikeRain
问题
- 什么是闭包? 有什么作用
MDN:闭包是指能够访问自由变量的函数(变量在本地使用,但在闭包中定义)。换句话说,定义在闭包中的函数可以“记忆”它被创建时候的环境。
<script type="text/javascript">
var i = 23333;
function f(){
function g(){
i = 502;
}
return g;
}
var func = f();
func();
//闭包的主要思想,这样函数内部的局部变量就会一直保留下来,这样外部作用域下访问函数局部变量,好像内部变量被拉到了台面上,可以被外部全局访问,
</script>
→自己的理解就是弄一个即时运行的函数,里面再套一个函数,外面的即时运行的函数等同于给出了一个停留空间,让内部的函数可以每次都运行出每个步骤的结果。(我的表达很混乱)
- setTimeout 0 有什么作用
setTimeout(function(){
//do
},0)
setTimeout 0;是会以0毫秒的延迟来调用这个setTimeout(),虽然这样,但是这个函数也是不会立即执行,反而会吧这个函数放到队列后面,等到前面的事件处理完毕后再运行。这是一种异步执行。
代码题
1.下面的代码输出多少?修改代码让 fnArr[i]()
输出 i。使用两种以上的方法
var fnArr = [];
for(var i = 0; i < 10; i++) {
fnArr[i] = function() {
return i;
};
}
console.log(fnArr[3]()); //一直10
//答
<script type="text/javascript">
var fnArr = [];
for(var i = 0; i < 10; i++) {
(function(n) {
fnArr[i] = function() {
return n;
};
})(i);
}
console.log(fnArr[3]()); //3
//用外面一层封装一个即时运行函数的方法
</script>
<script type="text/javascript">
var fnArr = [];
for(var i = 0; i < 10; i++) {
fnArr[i] = (function(n) {
return function(){
return n;
};
})(i);
}
console.log(fnArr[3]()); //3
//直接把变量传递到内部的函数子函数,形成闭包
</script>
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
//答
<script type="text/javascript">
var Car = (function() {
var speed = 0;
function setSpeed(i) {
speed = i;
}
function getSpeed() {
return speed;
}
function accelerate() {
speed += 10;
}
function decelerate() {
speed -= 10;
}
function getStatus() {
if(speed > 0) {
return "running";
} else {
return "stop";
}
}
return {
'setSpeed': setSpeed,
'getSpeed': getSpeed,
'accelerate': accelerate,
'decelerate': decelerate,
'getStatus': getStatus,
'speed': 'error'
};
}());
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
</script>
3.写一个函数使用setTimeout
模拟setInterval
的功能
<script type="text/javascript">
var i = 0;
var clock = setTimeout(function(){
setTimeout(arguments.callee,1000);//自己调用自己,这里的1000是自己调用自己的时间间隔,同setInterval
console.log(i++);
},0);
</script>
4.写一个函数,计算setTimeout最小时间粒度
<script type="text/javascript">
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)
}
</script>
5.下面这段代码输出结果是? 为什么?
<script type="text/javascript">
var a = 1;
setTimeout(function() {
a = 2;
console.log(a);
}, 0);
var a;
console.log(a);
a = 3;
console.log(a);
//将上面的代码根据运行优先级调整顺序后
var a;
a = 1;
console.log(a);
a = 3;
console.log(a);
setTimeout(function() {
a = 2;
console.log(a);
}, 0);
//setTimeout如果延迟设置为0,那么它的优先级会拉倒最后面........
</script>
6.下面这段代码输出结果是? 为什么?
var flag = true;
setTimeout(function(){
flag = false;
},0)
while(flag){}
console.log(flag);
//没有输出,因为setTimeout 0使得setTimeout的优先级是最后的,while判断被提前,while为true所以一直会循环输出空语句,就是木有输出啦~
7.下面这段代码输出?如何输出delayer: 0, delayer:1...(使用闭包来实现)
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log('delayer:' + i);
}, 0);
console.log(i);
}
//上面的代码因为优先执行for语句的时候i早就等于5了,再setTimeout迟了。之前的1234没有保留下来。
//下面是实现的代码
<script type="text/javascript">
for(var i = 0; i < 5; i++) {
setTimeout((function(n){
return function(){console.log('delayer'+ n)}
}(i)),0);
console.log(i);
}
</script>