1.什么是閉包? 有什么作用
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)?。。?/strong>
閉包由兩部分組成——函數(shù)以及創(chuàng)建該函數(shù)的環(huán)境,結(jié)合代碼解釋如下:
function outerFn(){
var a = 1;
function innerFn(){
console.log(a)
}
return innerFn
}
var fnRef = outerFn()
fnRef();
//上述代碼中:
1.閉包指的是能夠讀取outerFn函數(shù)內(nèi)部變量a的函數(shù)innerFn
2.這個(gè)閉包有函數(shù)innerFn以及創(chuàng)建該函數(shù)的環(huán)境——定義在outerFn函數(shù)內(nèi)的變量構(gòu)成
3.通過全局變量或是父函數(shù)返回值的兩種方法,可以實(shí)現(xiàn)在外部函數(shù)之外調(diào)用閉包,從而實(shí)現(xiàn)在外部函數(shù)之外引用外部函數(shù)內(nèi)的變量
閉包的作用有很多,這里簡(jiǎn)單介紹3種:隔離作用域、做計(jì)數(shù)器和聲明私有變量;
2.setTimeout 0 有什么作用
- setTimeout(func,miliseconds)的作用是延時(shí)指定的毫秒數(shù)再執(zhí)行指定代碼;
- setTimeout有最小的時(shí)間間隔(4ms-16ms),所以設(shè)置 setTimeout(func, 1)其實(shí)不會(huì)在1ms后執(zhí)行,而是再最小間隔之后比如4ms之后;
- setTimeout(funct, 0)時(shí),作用是讓func在現(xiàn)有的任務(wù)(腳本的同步任務(wù)和“任務(wù)隊(duì)列”中已有的事件)一結(jié)束就立刻執(zhí)行。也就是說,setTimeout(func,0)的作用是,盡可能早地執(zhí)行指定的任務(wù)
3.下面的代碼輸出多少?修改代碼讓fnArr[i]()輸出 i。使用兩種以上的方法

上述代碼輸出的是10,因?yàn)槊看伪闅v時(shí)只是將函數(shù)賦給fnArr[i],遍歷完成后此時(shí)i=10;
當(dāng)調(diào)用fnArr[i]()時(shí)此時(shí)會(huì)返回i的當(dāng)前值為10
//Method 1
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = (function(argus){
return function(){
return argus;
}
}(i));
}
console.log( fnArr[3]() );
console.log( fnArr[2]() );
//Method 2
var fnArr = [];
for (var i = 0; i < 10; i ++) {
(function (argus){
fnArr[argus] = function(){
return argus;
};
}(i))
}
console.log( fnArr[3]() );
console.log( fnArr[2]() );
4.使用閉包封裝一個(gè)汽車對(duì)象,可以通過如下方式獲取汽車狀態(tài)

var Car = (function(){
return{
speed: 0,
setSpeed: function(v){
v >= 0 ? this.speed = v : console.log('error');
},
getSpeed: function(){
console.log(this.speed);
},
acclerate: function(v){
v >= 0 ? this.speed += v : console.log('error');
},
decelerate: function(v){
v >= 0 ? this.speed -= v : console.log('error');
},
getStatus: function(){
this.speed > 0 ? console.log('running'):console.log('stop');
}
}
}());
5.寫一個(gè)函數(shù)使用setTimeout模擬setInterval的功能
function hello(){
console.log('hello world!')
};
setInterval(hello,1000)
//setTimeout模擬setInterval
function mockSetInterval(){
setTimeout(function(){
setTimeout(arguments.callee,1000);
hello();
},1000)
}
6.寫一個(gè)函數(shù),計(jì)算setTimeout最小時(shí)間粒度
老師這道題不太懂,可是不寫又不太好,
所以摘錄了王歡同學(xué)的解答作為任務(wù)作業(yè),
希望可以上課時(shí)講講,(^-^)V
function getMini(){
var start = Date.now();
var i = 0;
var miniTime = 0;
function func(){
i++;
if(i === 1000){
clearTimeout(clock);
var end = Date.now();
console.log((end-start)/i+'ms');
}
clock = setTimeout(arguments.callee,0)
}
var clock = setTimeout(func,0)
}
getMini();
7.下面這段代碼輸出結(jié)果是? 為什么?

var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
1.初始變量a = 1,后面只聲明不賦值變量a時(shí),a的值將不變;
2.setTimeout()將在最后執(zhí)行;
3.在執(zhí)行上述代碼的第2個(gè)console.log()時(shí)輸出1;
4.執(zhí)行第3個(gè)console.log()時(shí)a已經(jīng)被賦值3,所以輸出3;
5.最后回來執(zhí)行setTimeout(),此時(shí)輸出函數(shù)內(nèi)部定義的變量a,輸出值為2;
8.下面這段代碼輸出結(jié)果是? 為什么?

沒有輸出內(nèi)容;
setTimeout(function(){flag = false;},0)表示將里面的function放到最后去執(zhí)行;
所以上述代碼可以寫成:
var flag = true;
while(flag){}
console.log(flag);
setTimeout(function(){flag = false;},0)
因?yàn)閒lag一開始為true,所以會(huì)一直執(zhí)行while循環(huán),而不會(huì)執(zhí)行下面的語句;
9.下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來實(shí)現(xiàn))

for(var i=0;i<5;i++){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
}
上述代碼執(zhí)行順序是:
先執(zhí)行console.log(i),依次輸出0,1,2,3,4
再執(zhí)行5次延時(shí)函數(shù),此時(shí)i = 5,所以依次輸出5次delayer:5
for(var i=0;i<5;i++){
setTimeout((function(arg){
return function(){console.log('delayer:'+arg)}
}(i)),0)
console.log(i);
}