JS进阶之高阶函数 | 青训营笔记

85 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第5天
在 JavaScript 中,函数是一种特殊类型的对象,可以将函数作为参数传递给另一个函数。所以就会出现另一个概念——高阶函数,本文将介绍高阶函数及其应用。

高阶函数

高阶函数英文叫 Higher-order function,简称 HOC 具有以下特点:

  • 以函数作为参数
  • 以函数作为返回值
  • 常用于作为函数装饰器

也就是说高阶函数是对其他函数进行操作的函数,可以将它们作为参数传递,或者是返回它们。

内置高阶函数

JavaScript 语言中内置了一些高阶函数,比如 Array.prototype.map,Array.prototype.filter 和 Array.prototype.reduce,它们接受一个函数作为参数,并应用这个函数到列表的每一个元素。

Array.prototype.map

map()方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。不改变原数组
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

const array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1); // 返回一个新数组,不改变原数组
// expected output: Array [2, 8, 18, 32]

Array.prototype.filter

filter()方法创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
filter 为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或等价于 true 的值的元素创建一个新数组。callback 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中。

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result); // 返回的新数组只包含满足条件的元素
// expected output: Array ["exuberant", "destruction", "present"]

Array.prototype.reduce

reduce()  方法对数组中的每个元素按序执行一个由您提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。
第一次执行回调函数时,不存在“上一次的计算结果”。如果需要回调函数从数组索引为 0 的元素开始执行,则需要传递初始值。否则,数组索引为 0 的元素将被作为初始值 initialValue,迭代器将从第二个元素开始执行(索引为 1 而不是 0)。
通常可以用来求和等操作

const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (previousValue, currentValue) => previousValue + currentValue
);
console.log(sumWithInitial);
// expected output: 10

高级用法——函数装饰器

防抖——debounce

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

就类似回城时被打断就要重新等待

function debounce(fn, delay) { 
    let timer 
    return function (...args) { 
        if (timer) { clearTimeout(timer) } 
        timer = setTimeout(() => { 
            fn.apply(this, args) 
        }, delay) 
     } 
}

这里开了一个定时器,如果定时器中的代码执行前又调用了就清除之前的定时器然后重新计时。

节流——throttle

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

就类似技能CD,CD好了才能放技能

function throttle(fn, delay) { 
    let last = 0 // 上次触发时间 
    return function (...args) { 
        const now = Date.now() 
        if (now - last > delay) { 
            last = now fn.apply(this, args) 
        } 
    } 
}

只有达到了规定的间隔时间才能执行第二次。