上周,在谈论记忆时,我随便丢掉了“高阶函数”一词。 尽管我现在很乐于抛弃像这样的术语,但我并不总是知道它们的含义。 本周,我们将研究什么是高阶函数,展示一些常见示例,并学习如何创建自己的函数。
从本质上讲,高阶函数只是一个接受函数作为参数或返回函数的函数。 借助一流的函数 ,这在JavaScript中是可能的,这意味着JavaScript中的函数可以像其他任何变量一样传递。 尽管这听起来很简单,但并没有充分体现出一流功能所具有的功能。
如果您编写JavaScript,则可能使用了高阶函数,甚至没有注意到。 如果您曾经用数组方法替换过for
循环,则可以使用高阶函数。 如果您曾经使用过AJAX调用的结果(没有async
/ await
),那么您已经使用了高阶函数( promise和callback都涉及高阶函数)。 如果您曾经编写过一个显示项目列表的React组件,那么您已经使用了高阶函数。 让我们看看这些例子:
const items = ['a', 'b', 'c', 'd', 'e']
// Instead of this for loop....
for(let i = 0; i < items.length - 1; i++) {
console.log(items[i]);
}
// We can use forEach, a higher-order function
// (forEach takes a function as an argument)
items.forEach((item) => console.log(item));
// Callbacks or promises, if you’re making
// asynchronous requests, you’re using
// higher-order functions
get('https://aws.random.cat/meow', (response) => {
putImageOnScreen(response.file);
});
get('https://random.dog/woof.json').then((response) => {
putImageOnScreen(response.file);
});
// In the React component below, map is used,
// which is a higher-order function
const myListComponent = (props) => {
return (
<ul>
{props.items.map((item) => {
return (<li key={item}>{item}</li>)
})}
</ul>
);
};
这些是接受函数作为参数的高阶函数的示例,但其中许多函数也返回函数。 如果您曾经见过带有两组括号的函数调用,那是一个高阶函数。 这种事情以前很少见,但是如果您完全使用Redux ,则可能使用了connect
函数,它是一个高阶函数:
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
在上面的例子中,我们用两个参数调用connect
,它返回一个函数,我们立即用一个参数调用它。 您可能还看到(或编写了)一个简单的日志库,该库使用函数作为返回值。 在下面的示例中,我们将创建一个记录器,在消息之前记录其上下文:
const createLogger = (context) => {
return (msg) => {
console.log(`${context}: ${msg}`);
}
};
const log = createLogger('myFile');
log('A very important message');
// logs out "myFile: A very important message"
上面的示例开始说明一些高阶函数的功能(另请参见我先前关于备忘录的文章 )。 请注意, createLogger
接受一个我们在返回的函数主体中引用的参数。 我们分配给变量log
那个返回函数仍然可以访问context
参数,因为它在定义函数的范围内。
有趣的事实:闭包使引用context
成为可能。 我不会在这里讨论闭包,因为它们应有其用,但可以将它们与高阶函数结合使用以产生一些非常有趣的效果。
例如,使用闭包和高阶函数曾经是我们在JavaScript中拥有“私有”或防篡改变量的唯一方法:
let protectedObject = (function() {
let myVar = 0;
return {
get: () => myVar,
increment: () => myVar++,
};
})();
protectedObject.get(); // returns 0
protectedObject.increment();
protectedObject.get(); // returns 1
myVar = 42; // whoops! you just created a global variable
protectedObject.get(); // still returns 1
但是,让我们不要迷失方向。 高阶函数不需要像闭包这样的东西。 它们只是将其他函数作为参数或返回函数的简单函数。 句号 如果您需要更多示例或进一步阅读,请查阅Marijn Haverbeke的 “ Eloquent JavaScript ”中有关高阶函数的 章节 。
有疑问或意见吗? 随时联系Twitter: @freethejazz 。
From: https://www.infoworld.com/article/3389361/javascript-tutorial-higher-order-functions.html