閉包是指有權訪問另一個函數做用域中的變量的函數,主要是下面兩點:面試
- 是一個函數
- 能訪問另一個函數做用域中的變量
// 木易楊
const add = (...args) => args.reduce((a, b) => a + b);
// 簡化寫法
function currying(func) {
const args = [];
return function result(...rest) {
if (rest.length === 0) {
return func(...args);
} else {
args.push(...rest);
return result;
}
}
}
const sum = currying(add);
sum(1,2)(3); // 未真正求值
sum(4); // 未真正求值
sum(); // 輸出 10
複製代碼
<!--1-->
setImmediate(() => {
console.log('setImmediate1')
setImmediate(() => {
console.log('setImmediate2')
})
process.nextTick(() => {
console.log('nextTick')
})
})
setImmediate(() => {
console.log('setImmediate3')
})
輸出:
setImmediate1
setImmediate3
nextTick
setImmediate2
<!--2-->
setImmediate(() => {
console.log(1)
setTimeout(() => {
console.log(2)
}, 100)
setImmediate(() => {
console.log(3)
})
process.nextTick(() => {
console.log(4)
})
})
process.nextTick(() => {
console.log(5)
setTimeout(() => {
console.log(6)
}, 100)
setImmediate(() => {
console.log(7)
})
process.nextTick(() => {
console.log(8)
})
})
console.log(9)
輸出:
9
5
8
1
7
4
3
6
2
複製代碼
new (帶參數列表)優先級大於new (無參數列表)bash
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2 new (Foo.getName)(); 因此這裏實際上將getName函數做爲了構造函數來執行
new Foo().getName();//3 (new Foo()).getName() 首先new有參數列表(18)跟點的優先級(18)是同級,同級的話按照從左向右的執行順序,因此先執行new有參數列表(18)再執行點的優先級(18),最後再函數調用(17)
new new Foo().getName();//3 new ((new Foo()).getName)(); 先初始化Foo的實例化對象,而後將其原型上的getName函數做爲構造函數再次new,因此最終結果爲3
複製代碼
window.onresize = throttleV2(myFunc, 50, 100);則意味着,50ms的間隔內連續觸發的調用,後一個調用會把前一個調用的等待處理掉,但每隔100ms至少執行一次。原理也很簡單,打時間tag,一開始記錄第一次調用的時間戳,而後每次調用函數都去拿最新的時間跟記錄時間比,超出給定的時間就執行一次,更新記錄時間。閉包
var throttleV2 = function(fn, delay, mustRunDelay){
var timer = null;
var t_start;
return function(){
var context = this, args = arguments, t_curr = +new Date();
clearTimeout(timer);
if(!t_start){
t_start = t_curr;
}
if(t_curr - t_start >= mustRunDelay){
fn.apply(context, args);
t_start = t_curr;
}
else {
timer = setTimeout(function(){
fn.apply(context, args);
}, delay);
}
};
};
window.onresize = throttleV2(myFunc, 50, 100);
複製代碼