这是我参与「第四届青训营 」笔记创作活动的的第9天
高阶函数HOF
- 以函数作为参数
- 以函数作为返回值
- 常用于作为函数装饰器【参数与返回值都是函数的话】
下方代码为等价高阶函数
function HOFO(fn) {
return function(...args) {
fn.apply(this, args);
}
}
常用高级函数
- once
- throttle【节流函数 => 一段时间内只调用最后一次】
function throttle(fn, time = 500) {
let timer;
return function (...args) {
if (timer === null) {
fn.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, time)
}
}
}
btn.onclick = throttle(function(e) {
circle.innerHTML = parseInt(circle.innerHTML) + 1;
circle.className = 'fade';
setTimeout(() => circle.className = '', 250);
})
- debounce【防抖 => 只调用最后一次】
function debounce(fn, dur) {
dur = dur || 100;
var timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, dur)
}
}
- consumer
function consumer(fn, time) {
let tasks = [], timer;
return function(...args) {
tasks.push(fn.bind(this, ...args));
if (timer === null){
timer = setInterval(() => {
tasks.shift().call(this);
if(tasks.length <= 0) {
clearInterval(timer);
timer = null;
}
}, time)
}
}
}
纯函数
输入相同的参数,得到的输出一定是相同的
可以用console.assert()进行代码的简单判定
代码的可读性、可拓展性
交通红绿灯的切换,每隔一秒进行切换
一、直接使用setTimeout进行嵌套使用
- 数据抽象 - 将红绿灯的状态和持续时间抽象出来 => 状态列表
const traffic = document.getElementById('traffic')
const stateList = {
{state: 'wait', last: 1000},
{state: 'stop', last: 3000},
{state: 'pass', last: 3000},
}
function start(traffic, stateList) {
function applyState(stateIdx) {
const {state, last} = stateList[stateIndex];
traffic.className = state;
setTimeout(() => {
applyState([stateIdx + 1] % stateList.length);
}, last)
}
applyState(0);
}
start(traffic, stateList);
- 过程抽象 => 更有灵活性和拓展性
const traffic = document.getElementById('traffic')
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function poll(...fnList) {
let stateIndex = 0;
return async function(...args) {
let fn = fnList[stateIndex++ % fnList.length];
return await fn.apply(this.args);
}
}
async function setState(state, ms) {
traffic.className = state;
await wait(ms);
}
let trafficStatePoll = poll(
setState.bind(null, 'wait', 1000),
setState.bind(null, 'stop', 1000),
setState.bind(null, 'pass', 1000),
)
(async function() {
while(1) {
await trafficState();
}
})()
- 异步 + 函数式