問(wèn)題
1. 什么是閉包? 有什么作用?
- 概念:閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。由于在Javascript語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,因此可以把閉包簡(jiǎn)單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”。所以,在本職上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁。
- 作用:一是可以讀取函數(shù)內(nèi)部的變量;二是讓變量的值始終保持在內(nèi)存中。
2. setTimeout 0 有什么作用?
- 實(shí)現(xiàn)javascript的異步; 正常情況下javascript都是按照順序執(zhí)行,但可以利用 setTimeout延時(shí)0ms(setTimeout 0 )來(lái)讓該語(yǔ)句后面的語(yǔ)句執(zhí)行完再執(zhí)行語(yǔ)句本身。
- 在事件中,setTimeout會(huì)在其完成當(dāng)前任何延宕事件的事件處理器的執(zhí)行,以及完成文檔當(dāng)前狀態(tài)更新后,告訴瀏覽器去啟用 setTimeout內(nèi)注冊(cè)的函數(shù)。
代碼題
1. 下面的代碼輸出多少?修改代碼讓fnArri 輸出 i。使用兩種以上的方法
<pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = function(){ return i; }; } console.log( fnArr[3]() ); //
</pre>
方法一:立即執(zhí)行函數(shù)中利用臨時(shí)變量保存i值
<pre>var fnArr = []; for (var i = 0; i < 10; i ++) { (function(n){ var n = i; fnArr[i] = function(){ return n; }; })() } console.log( fnArr[3]() );
</pre>
方法二:賦值給立即執(zhí)行函數(shù),外部需要傳遞參數(shù)
<pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(i){ return function(){ return i; } })(i); } console.log( fnArr[3]() );
</pre>
方法三:賦值給立即執(zhí)行函數(shù),聲明一個(gè)臨時(shí)變量,外部不需要傳遞參數(shù)
<pre>var fnArr = []; for (var i = 0; i < 10; i ++) { fnArr[i] = (function(n){ var n = i; return function(){ return n; } })() } console.log( fnArr[3]() );
</pre>
2. 使用閉包封裝一個(gè)汽車(chē)對(duì)象,可以通過(guò)如下方式獲取汽車(chē)狀態(tài)
<pre>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
</pre>
代碼如下:
<pre>var Car = (function(){ var speed = 0; function setSpeed(n){ speed = n; } function getSpeed(){ console.log(speed); return speed; } function accelerate(){ speed +=10; } function decelerate(){ speed -=10; } function getStatus(){ if (speed>0){ console.log('running') }else{ console.log('stop') } } return { setSpeed:setSpeed, getSpeed:getSpeed, accelerate:accelerate, decelerate:decelerate, getStatus:getStatus } }());
</pre>
輸出結(jié)果:
3. 寫(xiě)一個(gè)函數(shù)使用setTimeout模擬setInterval的功能
setTimeout函數(shù)用來(lái)指定某個(gè)函數(shù)或某段代碼,在多少毫秒之后執(zhí)行。它返回一個(gè)整數(shù),表示定時(shí)器的編號(hào),以后可以用來(lái)取消這個(gè)定時(shí)器。setInterval函數(shù)的用法與setTimeout完全一致,區(qū)別僅僅在于setInterval指定某個(gè)任務(wù)每隔一段時(shí)間就執(zhí)行一次,也就是無(wú)限次的定時(shí)執(zhí)行。
如果用setTimeout實(shí)現(xiàn)setInerval的功能,就需要在執(zhí)行的程序中再定時(shí)調(diào)用自己才行。
代碼如下:
<pre>`
var i = 0;
function intv( ) {
setTimeout (function( ) {
console.log(++i);
intv( );
}, 1000)
}
intv( );
`</pre>
輸出結(jié)果:
4. 寫(xiě)一個(gè)函數(shù),計(jì)算setTimeout平均[備注:新加]最小時(shí)間粒度
代碼如下:
<pre>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) }
</pre>
5. 下面這段代碼輸出結(jié)果是? 為什么?
<pre>var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0); var a ; console.log(a); a = 3; console.log(a);
</pre>
分析:
<pre>var a = 1; setTimeout(function(){ a = 2; console.log(a); }, 0);//最后執(zhí)行,輸出結(jié)果為2 var a ;//聲明變量a,此時(shí)a的值仍為1 console.log(a);//輸出結(jié)果為1 a = 3;// 給a重新賦值為3 console.log(a);//輸出結(jié)果為3
</pre>
輸出結(jié)果為1,3,2,setTimeout函數(shù)必須要等到當(dāng)前腳本的同步任務(wù)和“任務(wù)列隊(duì)”中已有的事件全部處理完成之后,才會(huì)執(zhí)行setTimeout指定的任務(wù),所以最后輸出2。
6. 下面這段代碼輸出結(jié)果是? 為什么?
<pre>var flag = true; setTimeout(function(){ flag = false; },0) while(flag){} console.log(flag);
</pre>
沒(méi)有輸出。因?yàn)閟etTimeout是在執(zhí)行完其他代碼之后再執(zhí)行,所以在執(zhí)行完第一句之后,就到了下面的while循環(huán),而while判斷為真,flag為true,為死循環(huán),執(zhí)行空語(yǔ)句,無(wú)輸出。
7. 下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來(lái)實(shí)現(xiàn))
<pre>for(var i=0;i<5;i++){ setTimeout(function(){ console.log('delayer:' + i ); }, 0); console.log(i); }
</pre>
方法一:
<pre>for(var i = 0;i<5;i++){ (function () { var n = i; setTimeout(function(){ console.log('delayer:' + n ); }, 0); })() console.log(i); }
</pre>
方法二:
<pre>for(var i = 0;i<5;i++){ setTimeout((function(n){ return function() { return console.log('delayer:' + n ); } }(i)),0) console.log(i); }
</pre>
本教程版權(quán)歸饑人谷和作者所有,轉(zhuǎn)載須說(shuō)明來(lái)源。