Currying (การคั่นฟังก์ชัน)
เทคนิคแปลงฟังก์ชันที่รับหลาย Parameters ให้กลายเป็น Chain ของฟังก์ชันที่รับ Parameter เดียว ทีละตัว
รูปแบบทั่วไป (Non-Curried)
function volume(length, width, height) {
return length * width * height;
}
volume(11, 2, 3); // 66 - ส่งทั้ง 3 พร้อมกัน
รูปแบบ Curried
function volume(length) {
return function(width) {
return function(height) {
return length * width * height;
};
};
}
volume(11)(2)(3); // 66 - ส่งทีละตัว
Arrow Function Version (ES6)
const volume = length => width => height => length * width * height;
volume(11)(2)(3); // 66
ประโยชน์ของ Currying
- Partial Application: สร้างฟังก์ชันเฉพาะเจาะจงจากฟังก์ชันทั่วไป
- Reusability: ใช้ซ้ำ Logic พร้อม Parameter ต่างๆ
- Event Handling: Bind Parameter ก่อน แล้วค่อย Attach Handler
- Function Composition: รวมฟังก์ชันเล็กๆ เป็นใหญ่
ตัวอย่างใช้งานจริง: Partial Application
// Generic Logger
const log = level => message => console.log(`[${level}] ${message}`);
// สร้าง Specialized Loggers
const info = log('INFO');
const warn = log('WARN');
const error = log('ERROR');
info('Server started'); // [INFO] Server started
warn('Disk 90% full'); // [WARN] Disk 90% full
error('Connection lost'); // [ERROR] Connection lost
ตัวอย่าง: Event Handler với Currying
// แทนที่จะใช้ Closure ใน Loop (Classic Problem)
for (var i = 0; i < 3; i++) {
btn.addEventListener('click', (function(index) {
return function() { console.log('Button ' + index); };
})(i));
}
// Currying Approach
const handleClick = index => () => console.log('Button ' + index);
for (let i = 0; i < 3; i++) {
btn.addEventListener('click', handleClick(i));
}