Higher-Order Functions in JavaScript

Nếu bạn đang học JavaScript, bạn hẳn đã bắt gặp thuật ngữ Higher-Order Functions này. Mặc dù nghe có vẻ phức tạp cho dù bạn đã đọc nhiều bài viết về nó, nhưng với bài viết này, chúng ta sẽ đi qua một ví dụ cụ thể để biết Higher-Order Functions là gì?

Hôm trước chúng ta đã bàn luận về Currying một khái niệm cũng thuộc Higher-Order Functions, bạn nào chưa đọc thì có thể lướt qua.Javascript: Currying In JavaScript() 

Tham gia cùng chúng tôi:

Facebook: Cộng đồng lập trình javascript

Facebook Thảo luận về Javascript, ReactJS, VueJS, AngularJS Việt Nam

Không như những bài viết khác chỉ giải thích đại khái như là Higher-Order Functions là gì? Thì thay vào đó chúng ta sẽ đi vào ví dụ cụ thể để xem Higher-Order Functions hoạt động như thế nào? Nếu thông qua ví dụ mà bạn vẫn chưa hiểu thì chúng ta sẽ đi vào giải thích sâu hơn. 

Và cách mà chúng tôi muốn truyền đạt lại cho các bạn thông qua các ví dụ thì chúng tôi thấy phản hồi của các bạn về đa số là tốt hơn so với lý thuyết. Nào bây giờ chúng ta sẽ đi tìm hiểu. 

Giải thích Higher-Order Functions thông qua bài toán Tôi có một lớp học như sau:

var grades = [
    {name: 'John', grade: 8, sex: 'M'},
    {name: 'Sarah', grade: 12, sex: 'F'},
    {name: 'Bob', grade: 16, sex: 'M'},
    {name: 'Johnny', grade: 2, sex: 'M'},
    {name: 'Ethan', grade: 4, sex: 'M'},
    {name: 'Paula', grade: 18, sex: 'F'},
    {name: 'Donald', grade: 5, sex: 'M'},
    {name: 'Jennifer', grade: 13, sex: 'F'},
    {name: 'Courtney', grade: 15, sex: 'F'},
    {name: 'Jane', grade: 9, sex: 'F'}
]

Yêu cầu bài toán: 

  • Tìm thứ hạng trung bình của cả lớp 
  • Tìm thứ hạng trung bình của nam trong lớp 
  • Tìm thứ hạng trung bình của Nữ trong lớp 
  • Tìm thứ hạng cao nhất của Nam trong lớp 
  • Tìm thứ hạng cao nhất của Nữ trong lớp
  •  Tìm thứ hạng thấp nhất của Nam trong lớp 
  • Tìm thứ hạng thấp nhất của Nữ trong lớp 
  • Tìm thứ hạng cao nhất của cả lớp 
  • Tìm thứ hạng thấp nhất của cả lớp

Giả sử có hai cách làm của sinh viên A và B. Cả hai đều có tư duy lập trình nhưng hãy xem xét nhé. 

Đầu tiên chúng ta xem xét cách làm của sinh viên A.

 A1 - Tìm thứ hạng trung bình của cả lớp

let averageClass = grades.reduce(function (acc, curr) {
    return acc + curr.grade;
  }, 0) / grades.length;

console.log('Tìm thứ hạng trung bình của cả lớp>>', averageClass);// 10.2

A2 - Tìm thứ hạng trung bình của nam trong lớp

//tìm item Nam trong object
let findNam = grades.filter( function(student){
    return student.sex === 'M';
})
//sau đó chạy hàm này

let averageNam = findNam.reduce(function (acc, curr) {
    return acc + curr.grade;
  }, 0) / findNam.length;
console.log('Tìm thứ hạng trung bình của nam trong lớp>>', averageNam);// 7

A3 - Tìm thứ hạng trung bình của Nữ trong lớp

let findNu = grades.filter( function(student){
    return student.sex === 'F';
});


let averageNu = findNu.reduce(function (acc, curr) {
    return acc + curr.grade;
  }, 0) / findNu.length;
console.log('Tìm thứ hạng trung bình của Nữ trong lớp>>>', averageNu);// 13.4

A4 - Tìm thứ hạng cao nhất của Nam trong lớp

let gradeMaxNam = Math.max.apply(Math,findNam.map(function(o){return o.grade}));
console.log('Tìm thứ hạng cao nhất của Nam trong lớp>>>',gradeMaxNam);

A5 - Tìm thứ hạng cao nhất của Nữ trong lớp

let gradeMaxnu = Math.max.apply(Math,findNu.map(function(o){return o.grade}));
console.log('Tìm thứ hạng cao nhất của Nữ trong lớp>>>', gradeMaxnu);

A6 - Tìm thứ hạng cao nhất của Nam trong lớp

let gradeMinNam = Math.min.apply(Math,findNam.map(function(o){return o.grade}));
console.log('Tìm thứ hạng cao nhất của Nam trong lớp>>', gradeMinNam);

A7 - Tìm thứ hạng cao nhất của Nữ trong lớp

let gradeMinnu = Math.min.apply(Math,findNu.map(function(o){return o.grade}));
console.log('Tìm thứ hạng cao nhất của Nữ trong lớp>>',gradeMinnu);

A8 - Tìm thứ hạng cao nhất của cả lớp

let gradeMaxClass = Math.max.apply(Math,grades.map(function(o){return o.grade}));
console.log('Tìm thứ hạng cao nhất của cả lớp>>', gradeMaxClass);

A9 - Tìm thứ hạng thấp nhất của cả lớp

let gradeMinClass = Math.min.apply(Math,grades.map(function(o){return o.grade}));
console.log('Tìm thứ hạng thấp nhất của cả lớp>>>', gradeMinClass);

Kết quả của sinh viên A output:

 Tìm thứ hạng trung bình của cả lớp>> 10.2
(index):78 Tìm thứ hạng trung bình của nam trong lớp>> 7
(index):91 Tìm thứ hạng trung bình của Nữ trong lớp>>> 13.4
(index):96 Tìm thứ hạng cao nhất của Nam trong lớp>>> 16
(index):100 Tìm thứ hạng cao nhất của Nữ trong lớp>>> 18
(index):105 Tìm thứ hạng cao nhất của Nam trong lớp>> 2
(index):109 Tìm thứ hạng cao nhất của Nữ trong lớp>> 9
(index):113 Tìm thứ hạng cao nhất của cả lớp>> 18
(index):116 Tìm thứ hạng thấp nhất của cả lớp>>> 2

Đó là cách làm của sinh viên A. Chúng ta thấy A có hiểu biết nhiều về ES6, có thể nói là tốt. Chừng ấy đã đủ tốt với bạn?

Bây giờ chúng ta sẽ đi xem cách của sinh viên B với cách làm như sau, và anh ta có sử dụng Higher-Order Functions. Cách giải quyết của sinh viên B

let isBoy = student => student.sex === 'M'

let isGirl = student => student.sex === 'F'

let getBoys = grades => (
    grades.filter(isBoy)
)

let getGirls = grades => (
    grades.filter(isGirl)
)

let average = grades => (
    grades.reduce((acc, curr) => (
        acc + curr.grade
    ), 0) / grades.length
)

let maxGrade = grades => (
    Math.max(...grades.map(student => student.grade))
)

let minGrade = grades => (
    Math.min(...grades.map(student => student.grade))
)

let classroomAverage = average(grades) // 10.2
let boysAverage = average(getBoys(grades)) // 7
let girlsAverage = average(getGirls(grades)) // 13.4
let highestGrade = maxGrade(grades) // 18
let lowestGrade = minGrade(grades) // 2
let highestBoysGrade = maxGrade(getBoys(grades)) // 16
let lowestBoysGrade = minGrade(getBoys(grades)) // 2
let highestGirlsGrade = maxGrade(getGirls(grades)) // 18
let lowestGirlsGrade = minGrade(getGirls(grades)) // 9

Kết quả của sinh viên B output:

Tìm thứ hạng trung bình của cả lớp>> 10.2
(index):89 Tìm thứ hạng trung bình của nam trong lớp>> 7
(index):95 Tìm thứ hạng trung bình của Nữ trong lớp>>> 13.4
(index):99 Tìm thứ hạng cao nhất của Nam trong lớp>>> 16
(index):103 Tìm thứ hạng cao nhất của Nữ trong lớp>>> 18
(index):107 Tìm thứ hạng cao nhất của Nam trong lớp>> 2
(index):111 Tìm thứ hạng cao nhất của Nữ trong lớp>> 9
(index):115 Tìm thứ hạng cao nhất của cả lớp>> 18
(index):118 Tìm thứ hạng thấp nhất của cả lớp>>> 2

Thông qua hai cách thì các bạn cảm thấy cách nào tốt và có thể tai sử dụng lại cho những module tiếp theo. Đó là sự khác biết giữa without higher-order functions và higher-order functions. Đến đây hẳn các bạn đã hình dung được higher-order functions là gì chưa? 

#Higher-order functions là gì?

 Higher-order functions là các hàm lấy các hàm khác làm đối số hoặc trả về các hàm làm kết quả của chúng. Lấy một hàm khác làm đối số thường được gọi là hàm gọi lại, bởi vì nó được gọi lại bởi Higher-order functions. Đây là một khái niệm mà Javascript sử dụng rất nhiều. 

Higher-order functions được sử dụng rộng rãi trong JavaScript. Nếu bạn đã lập trình bằng JavaScript được một thời gian, bạn có thể đã sử dụng chúng mà không hề biết. Thường thì Higher-order functions là một trong nhiều hàm bậc cao hơn được tích hợp vào các method như sort, less, filter, forEach, map() là những ví dụ khác về các hàm bậc cao hơn được tích hợp vào ngôn ngữ. 

Đọc thêm Trường Hợp Nào Sử Dụng Map, Filter, Reduce Trong Javascript 

#Sức mạnh của Higher-order functions

Một trong những lợi thế lớn của việc sử dụng Higher-order functions khi chúng ta có thể là thành phần. Chúng ta có thể tạo các hàm nhỏ hơn chỉ chăm sóc một đoạn logic. Sau đó, chúng tôi soạn thảo các hàm phức tạp hơn bằng cách sử dụng các hàm nhỏ hơn khác nhau. 

Kỹ thuật này làm giảm lỗi và làm cho mã của chúng tôi dễ đọc và dễ hiểu hơn. Bằng cách học cách sử dụng các Higher-order functions, bạn có thể bắt đầu viết mã tốt hơn các developer khác. 

#Kết luận

Tham gia cùng chúng tôi:

Facebook: Cộng đồng lập trình javascript

Facebook Thảo luận về Javascript, ReactJS, VueJS, AngularJS Việt Nam

 

Thông qua bài này chúng ta đã học được các Higher-order functions là gì và vi dụ có thể để có thể thấy Higher-order functions đã giúp một developer phát triển skill như thế nào. Chúng tôi hy vọng bạn or một ai đó đã đọc bài viết này và đã áp dụng thành công trong các dự án khác. 

Bài viết được tham khảo nhiều nguồn để giúp bạn có cái nhìn sâu hơn 

https://blog.bitsrc.io/understanding-higher-order-functions-in-javascript-75461803bad

https://dev.to/damcosset/higher-order-functions-in-javascript-4j8b

https://anonystick.com/blog-developer/javascript-currying-in-javascript-2019050935248071.jsx