+3

Giới thiệu nhanh về Higher-order-functions trong JavaScript

Higher-Order Functions

Một function nhận vào và/hoặc trả về một function khác thì được gọi là highter-order function

Với function trong JavaScript bạn có thể làm:

  • Lưu trữ chúng dưới dạng biến
  • Sử dụng chúng trong array
  • chỉ định chúng như object properties (methods)
  • Chuyên chúng như các arguments
  • Return chúng từ các function khác

Như mọi loại kiểu dữ liệu khác thôi :v

Functions Operate trên các loại Data

String

sayHi = (name) => `Hi, ${name}!`;
result = sayHi('User');
console.log(result); // 'Hi, User!'

Numbers

double = (x) => x * 2;
result = double(4);
console.log(result); // 8

Booleans

getClearance = (allowed) => allowed ?
  'Access granted' :
  'Access denied';
result1 = getClearance(true);
result2 = getClearance(false);
console.log(result1); // 'Access granted'
console.log(result2); // 'Access denied'

### Objects
getFirstName = (obj) => obj.firstName;
result = getFirstName({
  firstName: 'Yazeed'
});
console.log(result); // 'Yazeed'

Arrays

len = (array) => array.length;
result = len([1, 2, 3]);
console.log(result); // 3

Đây là 5 loại kiểu dữ liệu chính First-class citizen trong mỗi ngôn ngữ.

Cái gì đã giúp chúng vào top đầu? Bạn có thể di chuyển, lưu trữ chúng trong biến, mảng sử dụng chúng làm đâu vào để tính toán.

Và Functions cũng có thể là dữ liệu

one

Dùng function như Arguments

isEven = (num) => num % 2 === 0;
result = [1, 2, 3, 4].filter(isEven);
console.log(result); // [2, 4]

Xem cách filter sử dụng isEven để quyết định xem sẽ giữ số nào. isEven là một function và cũng là một parameter cho một function khác.

Nó được gọi bởi filter cho mỗi số và trả về true hoặc false đế quyết đinh xem số đó có được giữ hay vào mảng mới hay không.

Returning Functions

add = (x) => (y) => x + y;

add yêu cầu 2 parameters nhưng không phải cùng 1 lúc. nó chỉ yêu cầu x, và return về một function, function này sẽ yêu cầu y.

Điều này chỉ khả thi vì JavaScript cho phép function return value (như strings, numbersm booleans,..).

Tất nhiên bạn vẫn có thể cung cấp cả x và y cùng lúc khi sử dụng cách gọi kép cả 2 function

result = add(10)(20);
console.log(result); // 30

Hoặc x trước và y sau:

add10 = add(10);
result = add10(20);
console.log(result); // 30

Giờ chúng ta cùng xem lại ví dụ cuối cùng nhé. add10 là kết quả của việc gọi add với một parameter. Thử logging nó trong console nào:

two

add10 lấy y và trả về x +y. Sau khi bạn cung cấp y nó sẽ tính toán và trả về kết quả cuối cho bạn.

three

Khả năng tái sử dụng cao

Có lẽ lợi ích tuyện vời nhât của HOFs là tái sử dụng. Nếu không có HOF các methods của Array map, filter và reduce sẽ không tồn tại! Đây là một list users. Chúng ta sẽ làm một vài tính toán với chúng.

users = [{
  name: 'Yazeed',
  age: 25
}, {
  name: 'Sam',
  age: 30
}, {
  name: 'Bill',
  age: 20
}];

Map

Nếu không có HOF chúng ta sẽ phải lặp kiểu như này:

getName = (user) => user.name;
usernames = [];
for (let i = 0; i < users.length; i++) {
  const name = getName(users[i]);
  usernames.push(name);
}
console.log(usernames);
// ["Yazeed", "Sam", "Bill"]

Làm bài trên với Map nào:

usernames = users.map(getName);
console.log(usernames);
// ["Yazeed", "Sam", "Bill"]

Filter

Khi không HOF chúng ta có thể làm kiểu này:

startsWithB = (string) => string
  .toLowerCase()
  .startsWith('b');
namesStartingWithB = [];
for (let i = 0; i < users.length; i++) {
  if (startsWithB(users[i].name)) {
    namesStartingWithB.push(users[i]);
  }
}
console.log(namesStartingWithB);
// [{ "name": "Bill", "age": 20 }]

và khi có HOF và filter

namesStartingWithB = users
  .filter((user) => startsWithB(user.name));
console.log(namesStartingWithB);
// [{ "name": "Bill", "age": 20 }]

Reduce

Chúng ta sẽ không thể có Reduce nếu không có HOF

total = 0;
for (let i = 0; i < users.length; i++) {
  total += users[i].age;
}
console.log(total);
// 75

Làm lại với reduce nào

totalAge = users
  .reduce((total, user) => user.age + total, 0);
console.log(totalAge);
// 75

Tổng kết

  • Strings, numbers, bools, arrays và object có thể chứa dưới dạng biến, array, và properties của methods.
  • với function JavaSCript cũng đối xử như vậy.
  • Điều này cho phép function hoạt đông trên các chức năng khác: **higher-order-functions. *Map, filter, và reduce là một số ví dụ để giúp việc xử lí data dễ dàng hơn nhiều cách thông thường.

Bài tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí