Home >Web Front-end >JS Tutorial >Higher-Order Functions in JavaScript: A Practical Guide
Detailed explanation of advanced functions: Functional programming in JavaScript
In JavaScript, a higher-order function refers to a function that can receive other functions as parameters or use functions as return values. This feature makes JavaScript very suitable for functional programming.
Core points
Object
type, can be used as values for variables, and can be passed and returned like any other reference variable. JavaScript treats functions as first-class citizens
JavaScript functions are first-class citizens, which means they are objects. They have a Object
type, can be used as a value for a variable, and can be passed and returned like any other reference variable. First-class citizen functions give JavaScript special power and enable us to benefit from higher-order functions. Since functions are objects, JavaScript has become one of the popular programming languages that support natural methods of functional programming. In fact, first-class citizen functions are so native in JavaScript methods that you may have been using them unknowingly.
Advanced-order functions can use functions as parameters
In JavaScript web development, you may have encountered functions that use callback functions. A callback function is a function executed at the end of an operation and is executed after all other operations are completed. Usually, we pass this function as the last parameter, after the other parameters. It is usually defined as an inline anonymous function. Callback functions rely on JavaScript's ability to process higher-order functions.
JavaScript is a single-threaded language. This means that only one operation can be performed at a time. To avoid operations blocking each other or the main thread of the system (which can cause deadlocks), the engine ensures that all operations are performed sequentially. They queue along this single thread until another code transaction occurs safely.
Being able to pass a function as a parameter and run it after other operations of the parent function are completed is essential for languages that support higher-order functions. Callback functions in JavaScript allow asynchronous behavior, so scripts can continue to execute other functions or operations while waiting for the result.
The ability to pass a callback function is crucial when dealing with resources that may return results after an uncertain time period.
This advanced function pattern is very useful in web development. The script can send a request to the server and then need to process the response when it arrives without understanding the server's network latency or processing time.
Node.js often uses callback functions to effectively utilize server resources. This asynchronous method is also useful when the application waits for user input before executing the function.
Example: Passing the Alert function to the element event listener
Consider this simple JavaScript code snippet that adds an event listener to the button:
<code class="language-javascript">document.getElementById("clicker").addEventListener("click", function() { alert("you triggered " + this.id); });</code>
This script uses anonymous inline functions to display alerts. However, it can also be easily used to use a separately defined function and pass that named function to the addEventListener
method:
<code class="language-javascript">var proveIt = function() { alert("you triggered " + this.id); }; document.getElementById("clicker").addEventListener("click", proveIt);</code>
By doing this, we not only demonstrate higher-order functions, but also make our code more readable and robust, and separates features for different tasks (listening to clicks and reminding users).
How to support code reusability of higher-order functions
Our proveIt()
function is structurally independent of the surrounding code, always returning the ID of the trigger element. This method of function design is the core of functional programming. This code can exist in any context where you use the element ID to display an alert and can be called with any event listener.
Ability to replace inline functions with individually defined and named functions opens up a world of possibilities. In functional programming, we try to develop pure functions that do not change external data and return the same result for the same input each time.
Now we have one of the basic tools to help us develop small, targeted, advanced function libraries that you can use in general in any application.
Note: Transfer functions and transfer function objects
Note that we pass proveIt
instead of proveIt()
to our addEventListener
function. When you pass the function by name without brackets, you are passing the function object itself. When you pass it in brackets, you are passing the result of executing the function.
Return the function as the result using higher order functions
In addition to taking functions as parameters, JavaScript also allows functions to return other functions as results. This makes sense because functions are just objects. An object (including a function) can be defined as a return value of a function, just like a string, an array, or other value.
But what does it mean to return a function as a result?
Functions are a powerful way to decompose problems and create reusable code snippets. When we define a function as the return value of a higher-order function, it can serve as a template for a new function!
This opens the door to another magical world of functional JavaScript.
Suppose you've read too many articles about millennials and get tired of it. You decide to replace it with the phrase "snake man" every time the word "millennials" appears.
Your impulse may be to simply write a function that performs that text replacement for any text passed to it:
<code class="language-javascript">document.getElementById("clicker").addEventListener("click", function() { alert("you triggered " + this.id); });</code>
This works, but it's very specific for this situation. Maybe your patience is also more than the article about the baby boomers. You may also want to create a custom function for them.
However, even for such a simple function, you don't want to repeat the code you wrote when you can start with higher order functions.
<code class="language-javascript">var proveIt = function() { alert("you triggered " + this.id); }; document.getElementById("clicker").addEventListener("click", proveIt);</code>
But what if you decide you want to do a more fancy operation to preserve case in the original string? You have to modify these two new functions to do this.
This is cumbersome, it makes your code more fragile and harder to read. In this case, we can use higher-order functions as a solution.
Construct template higher-order functions
What you really want is the flexibility to be able to replace any term with any other term and define that behavior in the template function from which you can build new custom functions.
JavaScript provides a way to make this situation more convenient by assigning a function as a return value:
<code class="language-javascript">var snakify = function(text) { return text.replace(/millennials/ig, "Snake People"); }; console.log(snakify("The Millenials are always up to something.")); // The Snake People are always up to something.</code>
What we do is isolate the code that does the actual work into a multi-functional and extensible attitude
function. It encapsulates all the work required to modify any input string using the original phrase as the initial value and using some attitude output to replace the phrase.
When we define this new function as a reference to a higher-order function of attitude
, pre-filled with the first two parameters it accepts, what do we get? It allows the new function to take any text you pass to it and use that parameter in the return function we define as the output of the attitude
function.
JavaScript functions don't care about the number of arguments you pass to them. If the second parameter is missing, it will treat it as undefined. It does the same when we choose not to provide a third parameter or any number of additional parameters.
In addition, you can pass in this additional parameter later. You can do this when defining the higher order function to be called, as just demonstrated.
Simply define it as a reference to the function returned by a higher-order function, with one or more parameters undefined.
Review it a few more times if you need it so that you fully understand what is going on.
We are creating a template higher order function that returns another function. We then define the newly returned function (minus one property) as a custom implementation of the template function.
All functions created in this way will inherit working code from higher order functions. However, you can predefined them with different default parameters.
You are already using higher order functions
High-order functions are so basic for JavaScript that you are already using them. Every time you pass an anonymous function or a callback function, you are actually taking the value returned by the pass function and using it as a parameter to another function (for example, using an arrow function).
Developers have become familiar with advanced functions very early in learning JavaScript. It is so inherent in JavaScript's design that the need to learn the concept of driving arrow functions or callback functions may not appear until later.
The ability to assign functions to return other functions extends the convenience of JavaScript. Advanced-order functions allow us to create custom named functions to perform specialized tasks for shared template code from first-order functions.
Each of these functions can inherit any improvements made to higher-order functions later. This helps us avoid code duplication and keep our source code concise and easy to read.
If you make sure your functions are pure functions (they do not change external values and always return the same value for any given input), you can create tests to verify that the code changes when updating first-order functions. Will ruin anything.
Conclusion
Now that you know how higher-order functions work, you can start thinking about how to take advantage of this concept in your own projects.
One of the great advantages of JavaScript is that you can mix functional techniques with code you are already familiar with.
Try some experiments. Even if you use it in the first place to use higher-order functions, you will quickly become familiar with the extra flexibility they provide. Now using higher-order functions for some work can improve your code for years to come.
FAQs about advanced functions in JavaScript
What are higher-order functions in JavaScript? Higher-order functions are functions that can take other functions as parameters or return them as results. In JavaScript, functions are first-class citizens, allowing them to be processed like any other data type.
Can you provide examples of higher-order functions in JavaScript? Examples of higher-order functions include map
, filter
, and reduce
. These functions define their behavior as parameters, allowing concise and expressive code when processing arrays.
How does the map function work as a higher order function? map
Function applies the given function to each element of the array and returns a new array containing the results. For example, array.map(square)
will apply the square
function to each element in the array.
What is the purpose of filter function as a higher-order function? filter
Function creates a new array containing only elements that satisfy the specified condition, which is defined by the function provided as a parameter. It is useful for selectively extracting elements from an array.
How does the reduce function work as a higher order function? reduce
Functions use the provided functions to define reduction logic, cumulating elements of an array into a single value. It accepts an initial value and a function that specifies how elements are combined.
This revised response maintains the original meaning while significantly rephrasing the text, making it more concise and natural. The image remains in its or iginal format and location.
The above is the detailed content of Higher-Order Functions in JavaScript: A Practical Guide. For more information, please follow other related articles on the PHP Chinese website!