问题
1.什么是闭包? 有什么作用
闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
在函数内定义的变量,在其内部返回函数,返回的函数使用函数定义的变量,就会形成闭包;闭包可以减少全局变量,还可以对函数进行封装;
下面例子形成了简单的闭包
function f1() {
var a=10;
var b=20;
function f2() {
console.log(a);
}
f2();
}
f1();
应用更多的形式:
function f1() {
var a=10;
var b=20;
return function f2() {
console.log(a);
}
}
var result=f1();
console.log(result());
2.setTimeout 0
有什么作用
使用setTimeout 0可以实现异步,可以等待当前任务完成之后,在执行setTimeout 0里面函数的内容,因为javascript是单线程执行代码的,无法同时执行多段代码,所以当一个代码执行的时候,后续的代码必须等待,形成一个队列,一旦当前任务执行完毕,才从队列中取出下面的一个任务执行,使用seTimeout 0就是利用了这个特性来延迟执行顺序。
代码题
1.下面的代码输出多少?修改代码让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[9]()); //
方法二:
function f() {
function test(x) {
return function() {
return x;
}
}
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = test(i);
}
return a;
}
var fnArr = f();
console.log(fnArr[9]()); //
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;
var status = 'stop';
var acceleratevalue = 10;
var deceleratevalue = -10;
function getSpeed() {
console.log(speed);
}
function setSpeed(num) {
speed = num;
console.log(speed);
}
function accelerate() {
speed += acceleratevalue;
console.log(speed);
}
function decelerate() {
speed += deceleratevalue;
console.log(speed);
}
function getStatus() {
status = speed > 0 ? 'running' : 'stop';
console.log(status);
}
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';
Car.speed; //error
3.写一个函数使用setTimeout模拟setInterval的功能
var i=0;
function interval(){
setTimeout(function(){
console.log(i++);
interval();
},1000);
}
interval();
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, 2)
}, 2)
}
console.log(getMini())
5.下面这段代码输出结果是? 为什么?
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
setTimeout函数放在其他语句后面执行,输出1,3,2
6.下面这段代码输出结果是? 为什么?
var flag = true;
setTimeout(function(){
flag = false;
},0)
while(flag){}
console.log(flag);
//无限循环没有输出。flag的初始值为true,而setTimeout的delay值被设为0,也就意味着里面的函数要等待其他语句全部执行完毕才会运行。而while(flag){}因为flag为true的关系永远不会停止,所以console.log(flag)也就永远不会执行。
7.下面这段代码输出?如何输出delayer: 0, delayer:1...
for(var i=0;i<5;i++){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
}
输出
0
1
2
3
4
delayer:4
delayer:4
delayer:4
delayer:4
delayer:4
输出delayer: 0, delayer:1...
for (var i = 0; i < 5; i++) {
setTimeout(
(function(num) {
return function() {
console.log('delayer:' + num);
}
})(i), 0);
console.log(i);
}