- vừa được xem lúc

Blog#79: Understanding Currying Pattern in Javascript

0 0 24

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

Để giúp các bạn có thể nâng cao trình độ tiếng Anh, Blog này mình sẽ viết bằng tiếng Anh.

Mục tiêu sẽ là, sử dụng Technical Document để học Tiếng Anh. Mình sẽ cố gắng sử dụng ngữ pháp và từ vựng đơn giản nhất (level~A1/A2) để giúp các bạn đọc nó dễ dàng hơn.


Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

In functional programming, the currying pattern is a way of writing functions that allows us to partially apply arguments to a function. This means that we can create a new function by providing some, but not all, of the arguments that the original function expects. This can be useful for creating more specific functions that can be re-used in different parts of our code.

What is Currying?

Currying is the process of taking a function that expects multiple arguments and turning it into a sequence of functions that each expect just one argument. For example, consider the following function that adds two numbers together:

function add(x, y) { return x + y;
}

We can curry this function by writing a new function that takes the first argument x and returns a new function that expects the second argument y. Here's how we could do this:

function add(x) { return function(y) { return x + y; }
}

Now, instead of calling add(x, y), we can call add(x)(y). This might seem like a small change, but it allows us to do some interesting things.

Benefits of Currying

There are several benefits to using the currying pattern in our code:

1. Reusable Functions

One of the main benefits of currying is that it allows us to create more specific functions that can be re-used in different parts of our code. For example, consider the following function that multiplies a number by 10:

function multiplyBy10(x) { return x * 10;
}

This function is specific to multiplying by 10, so we couldn't use it to multiply by any other number. However, if we curry this function, we can create a more general function that can be used to multiply by any number:

function multiply(x) { return function(y) { return x * y; }
} const multiplyBy10 = multiply(10);
const multiplyBy5 = multiply(5);

Now we have two specific functions, multiplyBy10 and multiplyBy5, that can be re-used throughout our code.

2. Composability

Another benefit of currying is that it allows us to easily compose new functions from existing ones. For example, consider the following functions that add and multiply numbers:

function add(x, y) { return x + y;
} function multiply(x, y) { return x * y;
}

We can use currying to create a new function that first multiplies two numbers and then adds a third number to the result:

function add(x) { return function(y) { return x + y; }
} function multiply(x) { return function(y) { return x * y; }
} const multiplyAndAdd = x => y => z => add(multiply(x)(y))(z);

Now we can call multiplyAndAdd(2)(3)(4) to perform the calculation (2 * 3) + 4.

Real-World Examples of Currying in Javascript

Now that we've learned about the basics of currying and its benefits, let's take a look at some real-world examples of how we can use this pattern in our Javascript code.

1. Partial Function Application

One common use case for currying is to create a new function that has some of the arguments pre-filled. This is known as partial function application.

For example, consider the following function that calculates the total cost of an order, including sales tax:

function calculateTotal(price, taxRate) { return price + (price * taxRate);
}

If we want to create a new function that calculates the total cost of an order with a specific tax rate, we can use currying to do this:

function calculateTotal(price) { return function(taxRate) { return price + (price * taxRate); }
} const calculateTotalWithTax = calculateTotal(0.08);

Now we can call calculateTotalWithTax(100) to get the total cost of an order with a price of $100 and a tax rate of 8%.

2. Creating Higher-Order Functions

Another common use case for currying is to create higher-order functions, which are functions that take other functions as arguments or return them as output.

For example, consider the following function that takes an array of numbers and a callback function, and returns a new array with the callback function applied to each element:

function map(array, callback) { const newArray = []; for (const element of array) { newArray.push(callback(element)); } return newArray;
}

We can use currying to create a new function that pre-fills the callback argument:

function map(callback) { return function(array) { const newArray = []; for (const element of array) { newArray.push(callback(element)); } return newArray; }
} const mapWithMultiplyBy2 = map(x => x * 2);

Now we can call mapWithMultiplyBy2([1, 2, 3]) to get the array [2, 4, 6].

3. Creating Event Handlers

Currying can also be useful for creating event handlers in React or other Javascript libraries.

For example, consider the following function that handles a click event on a button:

function handleClick(event, id, name) { console.log(`Button ${id} with name ${name} was clicked!`); // Do something with `event`
}

We can use currying to create a new function that pre-fills the id and name arguments:

function handleClick(id, name) { return function(event) { console.log(`Button ${id} with name ${name} was clicked!`); // Do something with `event` }
} const handleClickWithIdAndName = handleClick(1, 'Submit Button');

Now we can pass handleClickWithIdAndName to the onClick prop of a button, and it will log the appropriate message when the button is clicked.

4. Creating Custom Iterators

Currying can also be useful for creating custom iterators in Javascript.

For example, consider the following function that iterates over an array of numbers and returns the sum:

function sum(array) { let total = 0; for (const element of array) { total += element; } return total;
}

We can use currying to create a new function that iterates over an array and applies a callback function to each element:

function iterate(callback) { return function(array) { let total = 0; for (const element of array) { total += callback(element); } return total; }
} const sum = iterate(x => x + 1); console.log('sum([1,2,3])', sum([1,2,3])) // 9

Now we can call sum([1, 2, 3]) to get the sum of the array [2, 3, 4].

Conclusion

In this article, we learned about the currying pattern in Javascript and how it can be used to create more specific, re-usable functions and improve the composability and readability of our code. We also looked at several real-world examples of how this pattern can be applied in practical situations. While currying may take some time to get used to, it can be a powerful tool in a functional programming workflow.

As always, I hope you enjoyed this article and learned something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 528

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 436

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 158

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 149

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 113

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 249