Soal 1Dengan const addFee = (price, fee = 500) => price + fee;, apa yang dikembalikan addFee(1000, undefined)?
Default Parameter dan Rest Parameter — Value Bawaan dan Cara Menampung Sisa Argument
Membahas default parameter, rest parameter yang mengumpulkan argument ke dalam array, dan pola options object.
Ada argument yang value-nya hampir selalu sama di setiap pemanggilan, seperti ongkos kirim atau tarif pajak. Kalau argument itu tidak diisi, tidak ada error yang muncul; kamu baru sadar ada yang terlewat saat undefined ikut tampil di output.
Artikel ini membahas default parameter, yang menentukan value untuk argument yang tidak diisi, rest parameter, yang menampung argument dalam jumlah berapa pun, dan pola options, yang mengoper pengaturan sebagai satu object.
Membuat Argument Boleh Dikosongkan — Default Parameter
Misalnya ada function yang menyusun data pemesanan ruang rapat, dengan durasi yang hampir selalu 1 jam dan tata letak yang hampir selalu model classroom. Kalau kamu tetap harus menulis ketiga argument di setiap pemanggilan, satu value yang sebenarnya ingin kamu ubah jadi tenggelam di antara yang lain.
Default parameter (cara menentukan lebih dulu value yang dipakai kalau argument tidak dioper) ditulis dengan menambahkan = di daftar parameter, seperti hours = 1. Argument untuk parameter yang punya value bawaan boleh dikosongkan oleh pemanggil.
// Value bawaan ditulis dengan menambahkan "= value" di daftar parameter
const reserveRoom = (roomName, hours = 1, layout = "classroom") => {
return `${roomName} / ${hours} jam / ${layout}`;
};
// Kalau argument ke-3 tidak diisi, value bawaan "classroom" yang dipakai
console.log(reserveRoom("Ruang A", 2)); // Ruang A / 2 jam / classroom
// Kalau value-nya dioper, value bawaan tidak dipakai
console.log(reserveRoom("Ruang A", 2, "boardroom")); // Ruang A / 2 jam / boardroom
// Kalau argument ke-2 juga tidak diisi, kedua value bawaan dipakai
console.log(reserveRoom("Ruang A")); // Ruang A / 1 jam / classroom
reserveRoom("Ruang A", 2) per posisi parameter. Walaupun ada value bawaan, value itu tidak dipakai kalau argument-nya dioper.Argument hanya bisa dikosongkan mulai dari sebelah kanan, jadi letakkan parameter yang punya value bawaan di bagian akhir. Kalaupun kamu hanya ingin mengubah argument ke-3, posisi ke-2 tetap harus diisi value.
Isi Argument yang Tidak Dioper — undefined dan Value Bawaan
Kalau argument untuk parameter tanpa value bawaan tidak diisi, perhitungan atau string yang memakainya tetap berjalan. Karena eksekusinya tidak berhenti, belakangan kamu harus mencari sendiri pemanggilan mana yang lupa mengopernya.
Parameter yang tidak menerima argument berisi undefined. Value bawaan hanya dipakai kalau argument-nya undefined — kalau kamu mengoper null, 0, atau string kosong, value yang kamu oper itulah yang dipakai.
const notifyStatus = (orderId, status = "Diterima") => `${orderId}: ${status}`;
// Dikosongkan maupun dioper undefined, keduanya memakai value bawaan
console.log(notifyStatus("A-1021")); // A-1021: Diterima
console.log(notifyStatus("A-1021", undefined)); // A-1021: Diterima
// null dianggap value yang dioper, jadi value bawaan tidak dipakai
console.log(notifyStatus("A-1021", null)); // A-1021: null
// Parameter tanpa value bawaan yang tidak diisi berisi undefined
const plainStatus = (orderId, status) => `${orderId}: ${status}`;
console.log(plainStatus("A-1021")); // A-1021: undefined
status yang dikosongkan berisi undefined, jadi ekspresi value bawaan dijalankan. null diperlakukan sebagai value yang dioper, jadi ekspresi value bawaan tidak dijalankan.Tabel di bawah menunjukkan isi status dan apa yang ditampilkan untuk tiap argument kedua yang dioper ke notifyStatus. Mengoper undefined memberi hasil yang sama dengan mengosongkan argument, sedangkan null, sama seperti string, ditampilkan apa adanya.
| Pemanggilan | Isi status | Yang ditampilkan |
|---|---|---|
| notifyStatus("A-1021") | Value bawaan, Diterima | A-1021: Diterima |
| notifyStatus("A-1021", "Dikirim") | Dikirim | A-1021: Dikirim |
| notifyStatus("A-1021", undefined) | Value bawaan, Diterima | A-1021: Diterima |
| notifyStatus("A-1021", null) | null | A-1021: null |
Kalau null yang Dioper, Value Bawaan Tidak Dipakai
null adalah value yang berarti "sengaja dikosongkan", jadi value bawaan di daftar parameter tidak menggantikannya. Kalau kamu tetap ingin memakai value cadangan saat respons API berisi null, jangan pasang value bawaan di parameter, tapi pakai ?? di dalam function, seperti const shown = status ?? "Diterima";.
Menampung Argument dalam Jumlah Berapa Pun — Rest Parameter
Ada function yang menerima jumlah value berbeda di setiap pemanggilan, seperti tag pada sebuah produk atau rincian di laporan pengeluaran. Walaupun kamu menyiapkan lima parameter, suatu saat akan ada pemanggilan yang butuh yang keenam, dan parameter yang tidak terpakai selalu berisi undefined.
Rest parameter (cara menerima sisa argument yang dikumpulkan ke dalam satu array; disebut juga variadic argument) ditulis sebagai ...labels di akhir daftar parameter. Simbol ... ini sama dengan yang dipakai untuk mengumpulkan sisa element saat destructuring, bedanya di sini yang dikumpulkan adalah argument. Rest parameter hanya boleh menjadi parameter terakhir; menaruh parameter lain setelahnya akan menghasilkan SyntaxError.
// Dengan menulis ...labels, argument yang diterima dikumpulkan ke dalam satu array
const buildTags = (...labels) => `Tag (${labels.length}): ${labels.join(" / ")}`;
console.log(buildTags("Gratis Ongkir", "Stok Ada")); // Tag (2): Gratis Ongkir / Stok Ada
console.log(buildTags("Baru")); // Tag (1): Baru
// Sebaliknya, ... di dalam tanda kurung pemanggilan mengubah array kembali menjadi argument
console.log(buildTags(...["Baru", "Terbatas"])); // Tag (2): Baru / Terbatas
// Kalau ada juga parameter yang diberi nama, taruh rest parameter di akhir
const buildNotice = (orderId, ...notes) => `${orderId} (${notes.join(", ")})`;
console.log(buildNotice("A-1021", "Berpendingin", "Jam antar")); // A-1021 (Berpendingin, Jam antar)
console.log(buildNotice("A-1022")); // A-1022 ()
orderId, dan sisanya masuk berurutan ke element notes. Rest parameter menerima semua yang tersisa setelah parameter yang diberi nama.Rest parameter tidak bisa diberi value bawaan, tapi kalau tidak ada argument yang dioper untuknya, notes berisi array kosong, bukan undefined. Sebaliknya, kalau kamu punya array dan ingin mengoper isinya sebagai argument satu per satu, tulis ... di dalam tanda kurung pemanggilan.
Mengoper Pengaturan dengan Nama — Options Object dan Destructuring
Kalau pengaturannya makin banyak, seperti saat mengirim email, pemanggilannya lama-lama jadi seperti sendMail(to, subject, false, true). Arti false dan true itu tidak bisa diketahui tanpa membuka definisi function-nya.
Dengan pola options (cara mengoper beberapa pengaturan yang dikumpulkan dalam satu object), sisi penerima melakukan destructuring pada object itu dan memberi value bawaan untuk tiap key. Untuk menangani pemanggilan yang tidak mengoper pengaturan sama sekali, tambahkan = {} setelah pola destructuring supaya object kosong yang dipakai kalau tidak ada object yang dioper.
// Makin banyak parameter, makin sulit mengetahui apa yang dioper sebuah pemanggilan
const sendMailOld = (to, subject, isUrgent, withPdf) =>
`${to} / ${subject} / ${isUrgent} / ${withPdf}`;
console.log(sendMailOld("budi@example.com", "Info pengiriman", false, true));
// budi@example.com / Info pengiriman / false / true
// Pola options: kumpulkan pengaturan dalam satu object, lalu lakukan destructuring di sisi penerima
const sendMail = (to, { subject = "Pemberitahuan", isUrgent = false } = {}) =>
`${to} / ${subject} / ${isUrgent}`;
console.log(sendMail("budi@example.com", { isUrgent: true })); // budi@example.com / Pemberitahuan / true
console.log(sendMail("budi@example.com")); // budi@example.com / Pemberitahuan / false
Alih-alih bergantung pada urutan parameter, setiap value diberi label lewat key-nya, jadi pemanggilan tetap mudah dibaca walaupun pengaturannya bertambah. Key dicocokkan berdasarkan nama, jadi walaupun urutan penulisannya berbeda, seperti { isUrgent: true, subject: "Kirim ulang" }, value yang diterima tetap sama.
Tanpa = {}, Hasilnya TypeError
Kalau kamu hanya menulis pola destructuring, seperti { subject = "Pemberitahuan" }, pemanggilan yang tidak mengisi argument kedua akan melempar TypeError: Cannot read properties of undefined (reading 'subject'). Penyebabnya, JavaScript mencoba membaca key dari undefined, yaitu isi parameter yang tidak diisi itu.
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Apa yang dikembalikan const countNotes = (id, ...notes) => notes.length; saat dipanggil sebagai countNotes("A-1021")?
Soal 3Apa yang dikembalikan const send = (to, { urgent = false } = {}) => urgent; saat dipanggil sebagai send("budi@example.com")?