Parameter vs argumen
Dua kata yang terus-menerus tertukar. Parameter adalah nama di definisi fungsi. Argumen adalah nilai yang kamu kirim saat memanggilnya. Idenya sama seperti di Python dan kebanyakan bahasa lain:
a dan b adalah parameter. 2 dan 3 adalah argumen. JavaScript memasangkannya berdasarkan posisi: argumen pertama ke parameter pertama, dan seterusnya. Perbedaannya kecil, tapi itulah kosakata yang dipakai pesan error dan MDN.
JavaScript longgar soal jumlah argumen
Tidak seperti banyak bahasa lain, JavaScript tidak peduli kalau kamu mengirim argumen terlalu sedikit atau terlalu banyak. Parameter yang tidak diisi menjadi undefined. Argumen berlebih diabaikan begitu saja:
Pemanggilan pertama mencetak Hello, Ada undefined: last tidak mendapat nilai, jadi isinya undefined, dan template literal dengan senang hati menyisipkannya. Tanpa error, tanpa peringatan. Kelonggaran ini kadang berguna dan kadang jadi sumber bug, dan justru karena itulah default parameter ada.
Memberi nilai default
Tulis = dan sebuah nilai setelah nama parameter. Kalau pemanggil tidak mengirim argumen itu (atau mengirim undefined), nilai default yang dipakai:
Ketiga pemanggilan berhasil. Yang pertama dan ketiga memakai default; yang kedua memakai nilai yang dikirim. Ini sintaks ES6. Sebelum 2015, kamu harus menulis name = name || "friend" di dalam badan fungsi, yang punya bug tersendiri pada nilai falsy seperti 0 dan "".
Default bisa berupa ekspresi apa pun, bukan hanya literal:
Ekspresinya dievaluasi setiap pemanggilan, bukan sekali saat fungsi didefinisikan. Jadi tidak ada jebakan default yang bisa berubah seperti di Python: setiap pemanggilan mendapat new Date() yang baru.
Hanya undefined yang memicu default
Inilah aturan yang mengejutkan banyak orang. Default dipakai saat argumennya undefined, bukan saat falsy, dan bukan saat null:
Hanya pemanggilan terakhir yang memakai "friend". Mengirim null secara eksplisit berarti kamu bilang "nilainya null", dan JavaScript memercayai ucapanmu. Sama halnya dengan string kosong dan nol: keduanya adalah nilai, bukan argumen yang hilang.
Kalau kamu ingin null diperlakukan sama seperti tidak dikirim, kamu harus menanganinya sendiri:
Operator ?? (nullish coalescing) menganggap null dan undefined sama-sama "tidak ada." Penjelasan lebih lanjut ada di bab berikutnya.
Default bisa merujuk ke parameter sebelumnya
Parameter dievaluasi dari kiri ke kanan, jadi default yang belakangan bisa memakai parameter mana pun yang muncul sebelumnya:
Pemanggilan dengan satu argumen menghasilkan kubus. Dua argumen menghasilkan prisma persegi. Arahnya penting: kamu tidak bisa merujuk ke parameter yang belum dideklarasikan:
function bad(a = b, b = 1) {
return a + b;
}
bad(); // ReferenceError: Cannot access 'b' before initialization
Aturannya sama seperti variabel yang dideklarasikan dengan let: memakai sebelum dideklarasikan adalah error.
Default bekerja sama dengan destructuring
Kamu bisa melakukan destructuring pada parameter sekaligus memberinya default. Ini pola yang umum untuk argumen berupa "options object":
Ada dua lapis default yang bekerja. Yang di dalam (role = "member", active = true) mengisi property yang tidak ada. Yang di luar, = {}, menangani kasus saat pemanggil tidak mengirim argumen sama sekali; tanpanya, createUser() akan mencoba melakukan destructuring pada undefined dan melempar error.
Polanya terlihat padat di awal, tapi ada di mana-mana dalam codebase JavaScript modern. Begitu matamu mengenali { ... } = {} sebagai "options dengan default", kamu bisa membacanya dengan cepat.
Melewati argumen di tengah
JavaScript tidak punya keyword argument seperti Python. Untuk melewati parameter di tengah dan memakai default-nya, kamu mengirim undefined secara eksplisit:
Mengirim undefined untuk prefix mempertahankan default-nya. Jelek memang. Kalau kamu sering menulis undefined di pemanggilan, itu tanda untuk beralih ke options object:
Sekarang pemanggil menyebutkan apa yang ingin ia timpa, dan urutannya tidak penting.
Default tidak dihitung dalam length
Detail kecil yang jarang penting tapi sesekali membingungkan. Property length milik sebuah fungsi melaporkan jumlah parameter sebelum parameter pertama yang punya default:
Library yang memeriksa fungsi (seperti beberapa alat testing dan DI) memakai length untuk menghitung parameter yang "wajib". Bagus untuk tahu bahwa aturan ini ada; tidak perlu dihafal kecuali kamu sedang menulis alat semacam itu.
Berikutnya: rest dan spread
Default menangani kasus saat kamu sudah tahu parameternya sejak awal. Kadang kamu tidak tahu: kamu ingin fungsi menerima argumen berapa pun banyaknya, atau meneruskan sekumpulan argumen ke fungsi lain. Untuk itulah ...rest dan operator spread, yang akan dibahas berikutnya.
Pertanyaan yang sering diajukan
Bagaimana cara memberi nilai default pada parameter di JavaScript?
Tulis = dan nilai default-nya setelah nama parameter di signature fungsi: function greet(name = 'friend') { ... }. Kalau pemanggil tidak mengirim nilai (atau mengirim undefined), nilai default yang dipakai. Ini sintaks ES6 dan berjalan di semua lingkungan JavaScript modern.
Apa bedanya parameter dan argumen?
Parameter adalah nama di definisi fungsi: function add(a, b) punya parameter a dan b. Argumen adalah nilai sebenarnya yang dikirim saat pemanggilan: add(2, 3) mengirim argumen 2 dan 3. Perbedaannya penting saat membaca pesan error dan dokumentasi.
Apakah default parameter dipakai saat aku mengirim null?
Tidak. Default hanya dipakai saat argumennya undefined (atau tidak dikirim sama sekali). Mengirim null secara eksplisit berarti 'aku memberimu nilai, dan nilainya null', jadi default dilewati. Ini sering menjebak orang yang terbiasa dengan bahasa yang menganggap null dan undefined sama.
Apakah nilai default bisa merujuk ke parameter lain?
Bisa. Parameter dievaluasi dari kiri ke kanan, jadi default parameter yang belakangan bisa memakai parameter sebelumnya: function box(width, height = width). Kamu juga bisa memanggil fungsi di nilai default, seperti function log(msg, time = Date.now()), dan ekspresinya dijalankan ulang di setiap pemanggilan.