Khái niệm
Higher-Order Function: Hàm nhận hàm làm tham số, trả về hàm, hoặc cả hai. Arrow function (ES6) làm cú pháp ngắn gọn hơn.
Ví dụ: Double Array Elements
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Higher-Order Arrow Functions</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; }
.sample, .result { font-size: 16px; font-weight: 500; margin: 10px 0; padding: 15px; border-radius: 4px; }
.sample { color: #6a1b9a; background: #f3e5f5; }
.result { color: #d32f2f; background: #ffebee; }
button { padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h1>Higher-Order Arrow Functions</h1>
<div class="sample" id="sample">[22, 33, 44, 55]</div>
<div class="result" id="result"></div>
<button id="btn">NHÂN ĐÔI TỪNG PHẦN TỬ</button>
<h3>Nhấn nút để nhân đôi mỗi phần tử của mảng</h3>
<script>
const sampleEle = document.getElementById('sample');
const resultEle = document.getElementById('result');
const btn = document.getElementById('btn');
// Arrow function: double number
const doubleNum = (ele) => ele * 2;
// Higher-order function: nhận array và function transform
const doubleArray = (arr, fn) => arr.map(fn);
const arr = [22, 33, 44, 55];
sampleEle.textContent = `Mảng gốc: [${arr}]`;
btn.addEventListener('click', () => {
const newArr = doubleArray(arr, doubleNum);
resultEle.textContent = `Mảng mới: [${newArr}]`;
});
</script>
</body>
</html>
Kết quả
Mảng gốc: [22, 33, 44, 55]
Mảng mới: [44, 66, 88, 110]
Các Higher-Order Functions tích sẵn của Array
| Method | Mô tả | Trả về |
|---|---|---|
map(fn) | Biến đổi mỗi phần tử | Array mới cùng length |
filter(fn) | Lọc phần tử thỏa điều kiện | Array mới (có thể rỗng) |
reduce(fn, initial) | Gộp thành 1 giá trị | Giá trị đơn |
forEach(fn) | Duyệt (không trả về) | undefined |
find(fn) | Tìm phần tử đầu thỏa điều kiện | Phần tử hoặc undefined |
some(fn) | Kiểm tra có ít nhất 1 thỏa | boolean |
every(fn) | Kiểm tra tất cả thỏa | boolean |
sort(fn) | Sắp xếp (mutate gốc) | Array gốc (sorted) |
flatMap(fn) | map + flat(1) | Array mới |
Ví dụ thực tế
1. Composition (Kết hợp hàm)
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const add1 = x => x + 1;
const double = x => x * 2;
const square = x => x * x;
const transform = pipe(add1, double, square);
console.log(transform(3)); // (3+1)*2 = 8 -> 8*8 = 64
2. Currying với Arrow Function
const multiply = a => b => a * b;
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
3. Callback Pattern
function fetchData(url, onSuccess, onError) {
fetch(url)
.then(res => res.json())
.then(onSuccess)
.catch(onError);
}
// Usage
fetchData('/api/users',
users => console.log(users), // onSuccess
err => console.error(err) // onError
);
4. Strategy Pattern
const validators = {
email: v => v.includes('@'),
phone: v => /^\d{10}$/.test(v),
required: v => v.trim() !== ''
};
function validate(field, rules) {
return rules.every(rule => validators[rule](field));
}
console.log(validate('test@mail.com', ['required', 'email'])); // true