惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Spread Privacy
Spread Privacy
K
Kaspersky official blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Forbes - Security
Forbes - Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Secure Thoughts
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
Security Latest
Security Latest
TaoSecurity Blog
TaoSecurity Blog
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Cloudbric
Cloudbric
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
H
Hacker News: Front Page
C
Cybersecurity and Infrastructure Security Agency CISA
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
AWS News Blog
AWS News Blog
AI
AI
G
GRAHAM CLULEY
IT之家
IT之家
P
Privacy & Cybersecurity Law Blog
L
Lohrmann on Cybersecurity
Last Week in AI
Last Week in AI
D
Docker
Recent Announcements
Recent Announcements
O
OpenAI News
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
S
Security @ Cisco Blogs
T
Troy Hunt's Blog
C
Check Point Blog
博客园 - 三生石上(FineUI控件)
A
About on SuperTechFans
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic

Dmitri Pavlutin Blog

Pure Functions in JavaScript: A Beginner's Guide Record Type in TypeScript: A Quick Intro How to Write Comments in React: The Good, the Bad and the Ugly 4 Ways to Create an Enum in JavaScript React forwardRef(): How to Pass Refs to Child Components TypeScript Function Types: A Beginner's Guide How to Use v-model to Access Input Values in Vue Mastering Vue refs: From Zero to Hero Environment Variables in JavaScript: process.env 5 Must-Know Differences Between ref() and reactive() in Vue How to Destructure Props in Vue (Composition API) Triangulation in Test-Driven Development How to Use nextTick() in Vue Programming to Interface Vs to Implementation A Smarter JavaScript Mapper: array.flatMap() Array Grouping in JavaScript: Object.groupBy() How to Access ES Module Metadata using import.meta JSON Modules in JavaScript How to Trim Strings in JavaScript TypeScript Function Overloading How to Debounce and Throttle Callbacks in Vue How to Show/Hide Elements in Vue Sparse vs Dense Arrays in JavaScript How to Fill an Array with Initial Values in JavaScript Covariance and Contravariance in TypeScript How to Use TypeScript with React Components Index Signatures in TypeScript How to Use React useReducer() Hook unknown vs any in TypeScript A Guide to React Context and useContext() Hook How to Use Promise.any() 2 Ways to Remove a Property from an Object in JavaScript 'return await promise' vs 'return promise' in JavaScript How to Use Promise.allSettled() How to Use fetch() with JSON JavaScript Promises: then(f,f) vs then(f).catch(f) What is a Promise in JavaScript? How to Use Promise.all() A Simple Guide to Component Props in React Don't Stop Me Now: How to Use React useTransition() hook A Simple Explanation of JavaScript Variables: const, let, var ES Modules Dynamic Import How to Memoize with React.useMemo() How to Cleanup Async Effects in React Why Math.max() Without Arguments Returns -Infinity How to Debounce and Throttle Callbacks in React Don't Confuse Function Expressions and Function Declarations in JavaScript How to Use ES Modules in Node.js Solving a Mystery Behavior of parseInt() in JavaScript How to Use Array Reduce Method in JavaScript 3 Ways to Merge Arrays in JavaScript A Guide to Jotai: the Minimalist React State Management Library The Difference Between Values and References in JavaScript How to Implement a Queue in JavaScript A Helpful Algorithm to Determine "this" value in JavaScript React useRef() Hook Explained in 3 Steps 7 Interview Questions on "this" keyword in JavaScript. Can You Answer Them? How to Greatly Enhance fetch() with the Decorator Pattern 7 Interview Questions on JavaScript Closures. Can You Answer Them? What's a Method in JavaScript? array.sort() Does Not Simply Sort Numbers in JavaScript How to Solve the Infinite Loop of React.useEffect() The New Array Method You'll Enjoy: array.at(index) What's the Difference between DOM Node and Element? Why Promises Are Faster Than setTimeout()? Everything About Callback Functions in JavaScript How React Updates State 5 Mistakes to Avoid When Using React Hooks 5 Best Practices to Write Quality JavaScript Variables Type checking in JavaScript: typeof and instanceof operators 3 Ways to Check if a Variable is Defined in JavaScript React Forms Tutorial: Access Input Values, Validate, Submit Forms Prototypal Inheritance in JavaScript How to Timeout a fetch() Request How to Learn JavaScript If You're a Beginner A Simple Explanation of React.useEffect() A Simple Explanation of JavaScript Iterators How to Use React Controlled Inputs Everything about null in JavaScript How to Use Fetch with async/await Getting Started with Arrow Functions in JavaScript An Interesting Explanation of async/await in JavaScript Front-end Architecture: Stable and Volatile Dependencies Is it Safe to Compare JavaScript Strings? How to Access Object's Keys, Values, and Entries in JavaScript What Actually is a String in JavaScript? 3 Ways to Shallow Clone Objects in JavaScript (w/ bonuses) Checking if an Array Contains a Value in JavaScript JavaScript Event Delegation: A Beginner's Guide How to Parse URL in JavaScript: hostname, pathname, query, hash 3 Ways to Detect an Array in JavaScript How to Get the Screen, Window, and Web Page Sizes in JavaScript 3 Ways to Check If an Object Has a Property/Key in JavaScript How to Compare Objects in JavaScript Object.is() vs Strict Equality Operator in JavaScript Own and Inherited Properties in JavaScript 5 Differences Between Arrow and Regular Functions How to Use Object Destructuring in JavaScript Your Guide to React.useCallback() 5 JavaScript Scope Gotchas
What are Higher-Order Functions in JavaScript?
Dmitri Pavlutin · 2021-10-07 · via Dmitri Pavlutin Blog

The usual way you think about JavaScript functions is as reusable pieces of code that make some calculations. The arguments are the function's input data, and the return value is the output.

Here's a simple function that sums an array of numbers:


function calculate(numbers) {

let sum = 0;

for (const number of numbers) {

sum = sum + number;

}

return sum;

}

calculate([1, 2, 4]); // => 7


The numbers are the input, and the function calculate() returns the sum — the output.

What about implementing a more universal function to support more operations on numbers: addition, multiplication, and more. How would you implement that?

Let's see what the concept of the higher-order functions is, and how it can make calculate() function more universal in regards to operations it can support.

1. Higher-order functions

Let's make a pause and think a bit about fundamentals.

In JavaScript, the functions can use primitive types (like numbers, strings), objects (like arrays, plain objects, regular expressions, etc) as arguments, and return a primitive type or object too.

In the previous example, calculate([1, 2, 4]) accepts an array of numbers as an argument, and returns the number 7 — the sum.

But is it possible to use functions as values? Assign functions themselves to variables, use them as arguments, or even return? Yes, that's possible!

All because functions in JavaScript are first-class citizens. This means that you can:

A. Assign functions to variables:


// Assign to variables

const hiFunction = function() {

return 'Hello!'

};

hiFunction(); // => 'Hello!'


B. Use functions as arguments to other functions:


// Use as arguments

function iUseFunction(func) {

return func();

}

iUseFunction(function () { return 42 }); // => 42


C. And even return functions from functions:


// Return function from function

function iReturnFunction() {

return function() { return 42 };

}

const myFunc = iReturnFunction();

myFunc(); // => 42


Finally, here's the interesting part:

The functions that use other functions as arguments or return functions are named higher-order functions.

In the previous examples, iUseFunction() is higher-order because it accepts a function as an argument. Also iReturnFunction() is a higher-order function because it returns another function.

On the other side, the functions that use only primitives or objects as arguments, and only return primitives or objects are named first-order functions.

In the previous examples, hiFunction() is a first-order function since it simply returns a number.

So, in JavaScript a function can be either first-order or higher-order.

That's interesting, but why are higher-order functions useful? Let's find out next!

2. The higher-order functions in practice

Let's recall the question from the post introduction. How to make the calculate() function support multiple operations on the array of numbers?

The answer is to make calculate() a higher-order function, and supply dynamically the operation in form of a function as an argument.

Let's modify the function to make it happen:


function calculate(operation, initialValue, numbers) {

let total = initialValue;

for (const number of numbers) {

total = operation(total, number);

}

return total;

}

function sum(n1, n2) {

return n1 + n2;

}

function multiply(n1, n2) {

return n1 * n2;

}

calculate(sum, 0, [1, 2, 4]); // => 7

calculate(multiply, 1, [1, 2, 4]); // => 8


Open the demo.

Here's what changed: calculate(operation, initialValue, numbers) accepts the first argument a function that describes the operation, the second argument as the initial value, and finally the third argument is the array of numbers.

Now calculate(operation, initialValue, numbers) is a higher-order function because it accepts a function as the first argument.

sum() is the function that describes the addition operation. calculate(sum, 0, [1, 2, 4]) is using this function to perform the sum of numbers.

Same way multiply() describes the multiplication operation. calculate(multiply, 1, [1, 2, 4]) is using multiply() function to perform the production of all numbers.

Also, in the invocation calculate(sum, 0, [1, 2, 4]), the first argument is also called a callback function. You could think that a higher-order function accepts or returns callback functions.

3. The benefits of higher-order functions

What's great is you can reuse the calculate() function to support multiple operations by providing different operation functions: addition, multiplication, and more.

Additionally, the concept of the higher-order function allows composability of functions. For example, you compose calculate() with sum() to calculate the sum of all numbers in an array. If you want to calculate the production, then you compose calculate() and multiply().

The composability of functions thanks to higher-order functions is an important instrument in functional programming.

The higher-order functions help reduce the code duplication and favor the single-responsibility principle.

4. Examples of higher-order functions

If you look closer at the built-in JavaScript function on arrays, strings, DOM methods, promise method — you could notice that many of them are higher-order functions as soon as they accept a function as an argument.

For example, the array.map(mapperFunc) method is a higher-order function because it accepts a mapper function as an argument:


const numbers = [1, 2, 4];

const doubles = numbers.map(function mapper(number) {

return 2 * number;

});

doubles; // [2, 4, 8]


element.addEventListener(type, handler) DOM method is also a higher-order function since it accepts as the second argument the event handler function:


document

.getElementById('#myButton')

.addEventListener('click', function handler() {

console.log('The button was clicked!');

});


5. Conclusion

Higher-order functions in JavaScript are a special category of functions that either accept functions as an argument or return functions.

On the other side, if the function uses only primitives or objects as arguments or return values, these functions are first-order.

Higher-order functions provide the reusability benefit: the main behavior is provided by the higher-order function itself, and by accepting a function as an argument you extend that behavior at your will.

Challenge: Is there a built-in higher-order method on the array object similar to calculate(operation, initialValue, numbers)? Write your guess in a comment below!