Angka, string, dan boolean diperlakukan sebagai nilai yang dapat disimpan, dioper, dan dikembalikan, dan pada JavaScript fungsi memperoleh perlakuan yang sama. Sifat ini disebut first-class, yaitu fungsi dapat mengikuti setiap operasi yang berlaku pada nilai lain tanpa aturan khusus. Topik ini menelusuri akibat praktisnya, mulai dari fungsi yang disimpan dalam variabel, array, dan object, fungsi yang dioper sebagai argumen, sampai fungsi yang dihasilkan oleh fungsi lain. Seluruh mekanisme ini menjadi bekal utama topik Callback dan pengolahan array.
Disimpan dalam variabel, array, dan object#
Deklarasi fungsi pada dasarnya membuat satu nilai bertipe fungsi lalu menautkannya pada nama. Karena itu fungsi dapat disalin ke variabel lain, disusun ke dalam array, dan disimpan sebagai properti object, dan semua wadah itu menganggapnya seperti menyimpan angka atau string. Menyimpan fungsi ke wadah tidak menjalankannya, yang berjalan hanya pemanggilan dengan tanda kurung.
Berkas berikut menempatkan dua fungsi yang sama ke tiga wadah berbeda.
// Fungsi disimpan dalam variabel, array, dan object seperti nilai lain.
function tambah(a, b) {
return a + b;
}
function kurang(a, b) {
return a - b;
}
const operasiTambah = tambah;
console.log(operasiTambah(30, 12));
const daftarOperasi = [tambah, kurang];
console.log(daftarOperasi[0](100, 25));
console.log(daftarOperasi[1](100, 25));
const kalkulator = {
tambah: tambah,
kurang: kurang,
};
console.log(kalkulator.tambah(40, 60));
console.log(kalkulator.kurang(40, 60));42
125
75
100
-20operasiTambah bukan salinan fungsi tambah, melainkan nama kedua yang menunjuk fungsi yang sama, sehingga operasiTambah(30, 12) menghasilkan 42 persis seperti pemanggilan aslinya. Di dalam array, fungsi dipilih lewat indeksnya, daftarOperasi[0](100, 25) memanggil tambah dan menghasilkan 125. Di dalam object, fungsi menjadi properti yang dipanggil lewat titik. Properti object yang berisi fungsi biasa disebut metode. Struktur object dibahas lebih rinci pada modul Object dan array.
Fungsi sebagai argumen#
Fungsi yang dioper sebagai argumen memberi pemanggil kendali atas satu bagian pekerjaan yang belum ditentukan. Fungsi penerima hanya menulis struktur umumnya, kapan dan berapa kali memanggil, sedangkan isi pekerjaannya datang dari argumen berupa fungsi. Pemisahan ini membuat satu fungsi penerima melayani banyak kebutuhan tanpa diubah sama sekali.
Berkas berikut memuat fungsi terapkanKeSemua yang strukturnya tetap, tetapi konversi suhunya ditentukan oleh argumen.
// Fungsi dioper sebagai argumen untuk dijalankan oleh fungsi penerima.
function celsiusKeFahrenheit(celsius) {
return (celsius * 9) / 5 + 32;
}
function celsiusKeReamur(celsius) {
return celsius * 0.8;
}
function terapkanKeSemua(daftarSuhu, konversi) {
const hasil = [];
for (const suhu of daftarSuhu) {
hasil.push(konversi(suhu));
}
return hasil;
}
const suhuRuangan = [20, 25, 30];
console.log(terapkanKeSemua(suhuRuangan, celsiusKeFahrenheit));
console.log(terapkanKeSemua(suhuRuangan, celsiusKeReamur));[ 68, 77, 86 ]
[ 16, 20, 24 ]terapkanKeSemua sama sekali tidak tahu rumus konversinya, ia hanya mengiterasi daftar suhu dan memanggil konversi untuk setiap elemennya. Pemanggilan pertama mengoper celsiusKeFahrenheit dan menghasilkan 68, 77, 86, sedangkan pemanggilan kedua mengoper celsiusKeReamur dan menghasilkan 16, 20, 24. Metode array bawaan seperti map bekerja dengan gagasan yang sama dan dibahas penuh pada modul Metode array dan gaya fungsional.
Fungsi yang mengembalikan fungsi#
Karena fungsi adalah nilai, fungsi juga dapat menjadi nilai balik dari fungsi lain. Fungsi pembuat menerima sebagian pengaturan, menyusun fungsi baru yang membawa pengaturan itu, lalu mengembalikannya. Hasilnya berupa deretan fungsi siap pakai yang dibuat dari satu cetakan yang sama.
Berkas berikut membuat dua fungsi pengali dari satu fungsi pembuat.
// Fungsi dapat dikembalikan sebagai nilai balik dari fungsi lain.
function buatPengali(faktor) {
const pengali = angka => angka * faktor;
return pengali;
}
const kaliDua = buatPengali(2);
const kaliSeratus = buatPengali(100);
console.log(kaliDua(21));
console.log(kaliSeratus(250));
console.log(buatPengali(3)(14));42
25000
42Setiap pemanggilan buatPengali menghasilkan fungsi pengali yang berbeda, kaliDua membawa faktor 2 dan menghasilkan 42 dari 21, sedangkan kaliSeratus membawa faktor 100 dan menghasilkan 25000 dari 250. Baris terakhir memanggil fungsi pembuatnya lalu langsung memanggil hasilnya dalam satu ekspresi, buatPengali(3)(14), dan menghasilkan 42. Fungsi hasil kembalian ini masih mengingat nilai faktor saat dibuat, dan penjelasan penuhnya menunggu topik closure di modul Scope dan closure.
Membandingkan fungsi seperti nilai lain#
Fungsi dibandingkan dengan aturan yang sama seperti object, yaitu lewat identitas, bukan lewat isinya. Operator typeof melaporkan tipe fungsi sebagai function, sedangkan operator === menghasilkan true hanya bila kedua sisi menunjuk fungsi yang sama persis. Dua fungsi yang tulisannya identik tetap dianggap berbeda bila dibuat dua kali.
function tambah(a, b) {
return a + b;
}
const tambahLagi = tambah;
const salinIsi = function (a, b) {
return a + b;
};
console.log(typeof tambah);
console.log(tambah === tambahLagi);
console.log(tambah === salinIsi);function
true
falsetambah === tambahLagi bernilai true karena keduanya satu fungsi yang sama, sedangkan tambah === salinIsi bernilai false meskipun tubuh keduanya identik, karena salinIsi dibuat sebagai fungsi yang terpisah. Perilaku ini menjelaskan banyak hal penting, misalnya mengapa penghapusan event listener menuntut rujukan fungsi yang sama persis, bukan fungsi yang tulisannya mirip.
Ringkasan#
- Fungsi adalah nilai first-class, dapat disimpan di variabel, array, dan object, serta dioper dan dikembalikan seperti nilai lain.
- Menyimpan fungsi hanya memindahkan rujukannya, sedangkan menjalankannya membutuhkan tanda kurung pemanggilan.
- Fungsi penerima yang mengoper pekerjaannya ke argumen berupa fungsi menjadi dapat dipakai ulang untuk banyak kebutuhan, seperti pada
terapkanKeSemua. - Fungsi dapat mengembalikan fungsi lain yang membawa pengaturan dari fungsi pembuatnya, dan perbandingannya mengikuti identitas rujukan, bukan kesamaan isi.
Referensi#
- Functions — MDN Web Docs — rujukan fungsi JavaScript, termasuk fungsi sebagai nilai dan ekspresi fungsi.
- First-class function — MDN Web Docs — penjelasan istilah first-class beserta akibatnya pada bahasa.
- Function expressions — The Modern JavaScript Tutorial — fungsi sebagai nilai yang disimpan ke variabel beserta contohnya.