Functions in JavaScript Have More Secrets Than You Think
Things that advanced JavaScript programmers must know.
Functions are a familiar syntax to every programmer. In JavaScript, functions have a very high status and are often referred to as first-class citizens. But are you really good at using functions?
Here I’ll introduce some advanced tips for using functions that I hope will help you. This article includes the following sections:
- Pure Function
- Higher-Order Function
- Function Caching
- Lazy Function
- Currying
- Function Compose
Pure Function
What is a pure function?
A function that meets both of the following conditions is called a pure function:
- It was always returned the same result if given the same arguments.
- No side effects occur during the execution of the function
Example 1:
function circleArea(radius){
return radius * radius * 3.14
}When the values of the radius are the same, the function always returns the same result. And the execution of the function has no effect on the outside of the function, so this is a pure function.
Example 2:
let counter = (function(){
let initValue = 0
return function(){
initValue++;
return initValue
}
})()
This counter function will run differently every time, so this is not a pure function.
Example 3:
let femaleCounter = 0;
let maleCounter = 0;function isMale(user){
if(user.sex = 'man'){
maleCounter++;
return true
}
return false
}In the example above, the function isMale, given the same argument, always has the same result, but it has side effects. The side effect is to change the value of the global variable maleCounter, so it is not pure.
What’s the use of pure functions?
Why do we distinguish pure functions from other functions? Because pure functions have many advantages, we can use pure functions to improve the quality of our code during the programming process.
- Pure functions are much clearer and easier to read
Each pure function always accomplishes a specific task and has an exact result. This will greatly improve the readability of the code and make it easier to write documents.
2. The compiler can do more optimization on pure functions
Let’s say I have a code snippet like this:
for (int i = 0; i < 1000; i++){
console.log(fun(10));
}If fun were not a pure function, then fun(10) would need to be executed 1,000 times while this code is running.
If fun were a pure function, the editor would be able to optimize the code at compile time. The optimized code might look like this:
let result = fun(10)
for (int i = 0; i < 1000; i++){
console.log(result);
}3. Pure functions are easier to test
Tests of pure functions do not need to be context-dependent. When we write unit tests for pure functions, we simply give an input value and assert that the output of the function meets our requirements.
A simple example: A pure function takes an array of numbers as an argument and increments each element of the array by 1.
const incrementNumbers = function(numbers){
// ...
}We just need to write the unit test for it like this:
let list = [1, 2, 3, 4, 5];assert.equals(incrementNumbers(list), [2, 3, 4, 5, 6])If it’s not a pure function, we have a lot of external factors to consider, and it’s not a simple task.
Higher-Order Function
What is a higher-order function?
A higher-order function is a function that does at least one of the following:
- takes one or more functions as arguments
- returns a function as its result.
Using higher-order functions can increase the flexibility of our code, allowing us to write a more concise and efficient code.
Let’s say we now have an array of integers, and we want to create a new array. The elements of the new array have the same length as the original array, and the value of the corresponding element is twice the value of the original array.
Without using higher-order functions, we might write like this:
const arr1 = [1, 2, 3];
const arr2 = [];for (let i = 0; i < arr1.length; i++) {
arr2.push(arr1[i] * 2);
}In JavaScript, the array object has a map() method.
The
map(callback)method creates a new array populated with the results of calling a provided function on every element in the calling array.
const arr1 = [1, 2, 3];
const arr2 = arr1.map(function(item) {
return item * 2;
});
console.log(arr2);The map function is a higher-order function.
Using higher-order functions correctly can improve the quality of our code. The next sections are all about higher-order functions, so let’s move on.
Function Caching
Let’s say we have a pure function that looks like this:

function computed(str) {
// Suppose the calculation in the funtion is very time consuming
console.log('2000s have passed')
// Suppose it is the result of the function
return 'a result'
}To increase the speed of the program, we want to cache the result of the function operation. When it is called later, if the parameters are the same, the function will no longer be executed, but the result in the cache will be returned directly. What can we do?
We can write a cached function to wrap around our target function. This cache function takes the target function as an argument and returns a new wrapped function. Inside the cached function, we can cache the result of the previous function call with an Object or Map.












