Di JavaScript, fungsi adalah nilai, sama kayak angka atau teks: bisa disimpan di variabel, dikirim ke fungsi lain, dan dikembalikan dari fungsi. Fungsi yang menerima fungsi lain atau mengembalikan fungsi disebut higher-order function. map, filter, dan reduce yang sudah kamu kenal termasuk di dalamnya.
🧪 Tebakan cepat: mana yang benar,
numbers.filter(isEven)ataunumbers.filter(isEven())? Tebak dulu, jawabannya ada di bagian "Kirim fungsi ke fungsi lain".
Kirim fungsi ke fungsi lain
const numbers = [1, 2, 3, 4, 5, 6];
const isEven = (n) => n % 2 === 0;
const multiplier = (factor) => (n) => n * factor;
const result = numbers.filter(isEven).map(multiplier(10));
console.log(result); // [20, 40, 60]
console.log(numbers); // [1, 2, 3, 4, 5, 6]
isEvenadalah fungsi yang menjawabtruekalau angkanya genap.n % 2adalah sisa bagi 2, dan angka genap sisanya 0.numbers.filter(isEven)menerima fungsiisEven, lalu memanggilnya buat tiap angka. Yang hasilnyatruelolos:[2, 4, 6].multiplier(10)mengembalikan fungsi baru,(n) => n * 10. Fungsi itulah yang dikirim kemap, danmapmemanggilnya buat tiap angka:[20, 40, 60].numbersgak berubah.filterdanmapselalu bikin array baru.
filter dan map menerima fungsi, multiplier mengembalikan fungsi: ketiganya higher-order function. Patokannya: kalau ada fungsi yang masuk sebagai argumen atau keluar sebagai hasil, itu higher-order function.
Jawaban tebakan: filter(isEven). isEven ditulis tanpa (), karena yang dikirim fungsinya. isEven() menjalankan fungsinya saat itu juga, tanpa angka, lalu cuma hasilnya yang dikirim. multiplier(10) justru ditulis dengan (), karena hasil panggilannya memang sebuah fungsi.
map, filter, dan reduce
map(fn)mengubah tiap item, jumlah item tetap:[1, 2, 3].map((n) => n * 2)menghasilkan[2, 4, 6].filter(fn)menyaring, cuma item yangfn-nyatrueyang tersisa:[1, 2, 3, 4].filter((n) => n > 2)menghasilkan[3, 4].reduce(fn, awal)melipat semua item jadi satu nilai:
const total = [1, 2, 3].reduce((acc, n) => acc + n, 0);
console.log(total); // 6
acc (accumulator) adalah hasil sementara. Dia mulai dari nilai awal 0, lalu tiap putaran acc + n jadi acc berikutnya: 0 + 1 = 1, 1 + 2 = 3, 3 + 3 = 6. Nilai awal itu penting: dengan 0, array kosong menghasilkan 0, bukan error.
Method-method ini bisa dirangkai, hasil yang satu langsung masuk ke berikutnya. [1, 2, 3, 4].filter((n) => n > 1).reduce((acc, n) => acc + n, 0) menyaring jadi [2, 3, 4], lalu menjumlahnya jadi 9.
⚠️ Jebakan yang sering ketemu
- Lupa
returndi callback berkurung kurawal.[1, 2, 3].map((n) => { n * 2; })menghasilkan[undefined, undefined, undefined]. Tulis(n) => n * 2atau(n) => { return n * 2; }. - Mengira
mapmengubah array aslinya.arr.map(fn)sendirian gak mengubaharr. Tampung hasilnya di variabel, atau langsungreturn arr.map(fn). reducetanpa nilai awal. Kalau array-nya kosong, misalnya karenafiltergak meloloskan apa pun,reducetanpa nilai awal bikin TypeError.
TL;DR: Higher-order function adalah fungsi yang menerima fungsi atau mengembalikan fungsi. map mengubah tiap item, filter menyaring dengan fungsi yang menjawab true atau false, dan reduce melipat semuanya jadi satu nilai mulai dari nilai awal, misalnya 0. Kirim fungsinya tanpa (), dan ingat ketiganya bikin array atau nilai baru, array aslinya gak berubah.