1.闭包
闭包是指有权访问另外一个函数作用域中的变量的函数,主要是下面两点:
- 是一个函数
- 能访问另外一个函数作用域中的变量
函数柯里化
// 木易杨
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
2. EventLoop
<!--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
3. 经典js new 面试题(注意后三个运算优先级)
new (带参数列表)优先级大于new (无参数列表)
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
4. 函数节流
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);