1.什么是閉包? 有什么作用?
<li>閉包是指有權訪問其他函數作用域中的變量的函數。
<li>詳細解釋:就是在一個函數中,父函數return出另一個子函數,并將子函數賦值給一個外部變量,使得此變量能夠訪問函數內部的值和變量,使得函數的內存不能釋放,因此生成一個閉包。
For example:
上面例子c作為一個外部函數,能夠訪問fn1和fn2的變量和值,因此這個c就是閉包!!!
<li>作用:</br>
1.可以訪問函數內部的變量和修改。</br>
2.讓函數內部的變量始終保存在內存中,不會因為函數執行完畢就銷毀。
<li>閉包的特點?
閉包的特點很鮮明,閉包內,變量無法釋放,無法被直接訪問;閉包可以被延遲執行。
<li>閉包的使用場景?
場景一:采用函數引用方式的setTimeout調用.
場景二:將函數關聯到對象的實例方法.
場景三:封裝相關的功能集
參考資料:<a >閉包使用場景</a>
2. setTimeout 0 有什么作用?
<li>setTimeout(func,ms)的作用是延遲指定毫秒數去執行此函數。
<li>setTimeout有最小時間間隔(4ms-16ms),因此即使你設置setTimeout(func,1)也不會在一毫秒之后執行,而是在最小時間間隔之后執行,比如4毫秒之后。
<li>setTimeout(func,0)的意思是,作用是讓f在現有的任務(腳本的同步任務和“消息隊列”指定的任務)一結束就立刻執行。簡單來說:就是當所有任務執行完成之后,馬上執行此函數。
3.代碼
下面的代碼輸出多少?修改代碼讓fnArri 輸出 i。使用兩種以上的方法
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() ); //
code1:
var fnArr = [];
for (var i = 0; i < 10; i ++) {
(function(n){
var n =i;
fnArr[n] = function(){
return n;
};
})(i)
}
console.log( fnArr[3]() );
code2:
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = (function(){
var n =i;
return function(){
return n;
}
})();
}
console.log( fnArr[3]() );
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
code
var Car = (function car(){
var speed = 0;
function setSpeed(n){
speed = n;
}
function getSpeed(){
console.log(speed);
}
function accelerate(){
speed = speed + 10;
}
function decelerate(){
speed = speed - 10;
}
function getStatus(){
if(speed > 0){
return 'running';
}
if(speed = 0){
return 'stop';
}
}
return {
'setSpeed':setSpeed,
'getSpeed':getSpeed,
'accelerate':accelerate,
'decelerate':decelerate,
'getStatus':getStatus,
'speed':'error'
}
})();
3.寫一個函數使用setTimeout模擬setInterval的功能?
code
var i = 0 ;
function copySetinterval(){
setTimeout(function (){
console.log(i++);
copySetinterval();
},1000);
};
copySetinterval()
寫一個函數,計算setTimeout平均最小時間粒度
function getMini(){
var i = 0;
var start = Date.now();
var time = setTimeout(function (){
i++;
if(i === 1000){
clearTimeout(time);
var end = Date.now();
console.log((end-start)/i);
}
time = setTimeout(arguments.callee,0);
} ,0)
}
getMini()
4.下面這段代碼輸出結果是? 為什么?
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
變形得:
var a = 1;
var a ;
console.log(a);
a = 3;
console.log(a);
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
答:執行結果按順序排列,分別是1,3,2。
解釋:因為setTimeout是指所有任務執行完畢后,延遲執行多少毫秒執行函數,因此setTimeout是最后執行,如上面的代碼,首先定義變量a=1,因此第一個console.log(a)為1,之后將3賦給變量a,因此第二個console.log(a)為3,最后執行setTimeout,里面的匿名函數將2賦值給a,因此第三個console.log輸出是2.
5.下面這段代碼輸出結果是? 為什么?
var flag = true;
setTimeout(function(){
flag = false;
},0)
while(flag){}
console.log(flag);
變形得
var flag = true; // 把布爾值true賦值給變量flag;
while(flag){} //當flag為true時執行while循環,但是while循環是個死循環,所以后面代碼全部不會執行;
console.log(flag);
setTimeout(function(){
flag = false;
},0)
因此沒有輸出。
6.下面這段代碼輸出?如何輸出delayer: 0, delayer:1...(使用閉包來實現)
for(var i=0;i<5;i++){
setTimeout(function(){
console.log('delayer:' + i );
}, 0);
console.log(i);
}
code
for(var i=0;i<5;i++){
(function(){
var n =i ;
setTimeout(function(){
console.log('delayer:' + n );
}, 0);
console.log(n);})(i)
}
版權歸饑人谷peter和饑人谷所有,若有轉載,請注明來源
感謝瓜子觀眾: