个人感觉不同语言走到最后都趋向于一致。拿filter、map这些函数来说,JS、JDK、Spark都有,谁能想象完全是三个行业(前端、后端、大数据)的语言,但是用法却完全一致。

在JavaScript的世界里,高阶函数就像是隐藏的宝藏,它们在数据整理、界面设计,甚至是算法编写的过程中都能成为你的得力助手。那么,高阶函数究竟有何奥秘呢?🤔

所谓高阶函数,其实不过是这样的函数:它们能够接收其他函数作为参数,也能够输出一个新的函数。概念上并不复杂吧?除了理论之外,让我们通过一些生动的实例来感受高阶函数的强大吧!🔥

1️⃣ 将函数作为参数传递

假设你想对一个数组中的每个元素应用一个函数。这时,.map()就派上用场了,它是JavaScript中的高阶函数之一。

示例:

const numbers = [1, 2, 3, 4, 5];

// HOF: Using map to double each number
const doubled = numbers.map(num => num * 2);

console.log(doubled); // [2, 4, 6, 8, 10]

💡 背后的原理:

  • .map() 能够接收一个函数(例如 num => num * 2)作为参数。
  • 它会将这个函数逐一作用于数组中的每个元素。

2️⃣ 返回新函数

在某些场景下,我们需要一个函数能够动态“制造”出另一个函数。🤯

来看一个例子:

我们定义一个 multiplyBy 函数,它能够根据传入的乘数生成新的乘法函数。

const multiplyBy = multiplier => number => number * multiplier;

// 基于multiplyBy,我们创建了两个特定的乘法函数
const double = multiplyBy(2);
const triple = multiplyBy(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

💡 这么做的优势是什么?

这种方法使得逻辑变得更加灵活和可重用。你只需编写一次基础逻辑,就能根据需要随时“生成”出特定的函数。🚀

3️⃣ .filter()的妙用

在JavaScript的高阶函数中,.filter() 也称得上是一员“猛将”。它能帮你轻松地从数组中筛选出满足特定条件的元素。

举个例子:

const words = ["apple", "banana", "kiwi", "apricot"];

// 挑选出以 'a' 开头的单词
const startsWithA = words.filter(word => word.startsWith("a"));

console.log(startsWithA); // ["apple", "apricot"]

💡 高手秘籍:将 .map().filter() 结合使用,可以让你像编程高手一样流畅地进行链式操作。

第一次翻译(直译):

4️⃣ .reduce()的妙用

在JavaScript中,.reduce() 函数堪称“全能选手”,它能够将数组中的元素累积成一个值。

来看一个例子:

const prices = [10, 20, 30];

// 计算价格总和
const total = prices.reduce((sum, price) => sum + price, 0);

console.log(total); // 60

💡 实用场景:无论是进行数值求和,还是处理数组扁平化,.reduce() 都能成为你解决问题的得力助手。

5️⃣ 回调函数与事件监听器

没想到吧?addEventListener 这样的函数其实也是高阶函数的一种,因为它们能够接收回调函数作为参数。

举个例子:

document.querySelector("button").addEventListener("click", () => {
  console.log("按钮被点击了!🚀");
});

💡 原理: 你提供给 addEventListener 的函数,会在特定的操作(比如点击)触发时自动执行。

🤔 提问: 猜猜输出是什么?

const createCounter = () => {
  let count = 0;
  return () => ++count;
};

const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1()); // ?
console.log(counter1()); // ?
console.log(counter2()); // ?
console.log(counter2()); // ?