跟着月影学JavaScript简记 | 青训营笔记

56 阅读1分钟

这是我参与「第四届青训营 」笔记创作活动的的第9天

高阶函数HOF

  • 以函数作为参数
  • 以函数作为返回值
  • 常用于作为函数装饰器【参数与返回值都是函数的话】

image.png

下方代码为等价高阶函数

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)
        }
    }
}

image.png

image.png

image.png

纯函数

输入相同的参数,得到的输出一定是相同的
可以用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();
    }
})()
  • 异步 + 函数式

image.png