Parametre ve argüman farkı
Bu iki terim sürekli birbirine karıştırılıyor. Parametre, fonksiyon tanımında yer alan isimdir. Argüman ise fonksiyonu çağırırken geçtiğin değerdir. Mantık Python'daki ve diğer dillerin çoğundaki ile aynı:
a ve b birer parametre. 2 ve 3 ise argüman. JavaScript bunları sırasına göre eşler: ilk argüman ilk parametreye, sonraki sonrakine... Fark küçük görünse de hata mesajlarında ve MDN'de kullanılan terminoloji bu, o yüzden bilmekte fayda var.
JavaScript Argüman Sayısına Takılmaz
Pek çok dilin aksine, JavaScript fonksiyona eksik ya da fazla argüman geçmenizi umursamaz. Eksik kalan parametreler otomatik olarak undefined olur; fazladan gelenler ise sessizce yok sayılır:
İlk çağrı Merhaba, Ada undefined yazdırıyor — last parametresine değer gelmediği için undefined oluyor ve template literal bunu hiç sorun çıkarmadan olduğu gibi basıyor. Ne hata var, ne uyarı. Bu esneklik bazen işimizi görüyor, bazen de bug kaynağı oluyor. İşte tam da bu yüzden default parametreler var.
JavaScript'te Varsayılan Parametre Değeri Tanımlama
Parametre adının yanına = koyup bir değer yazmanız yeterli. Çağıran taraf o argümanı geçmezse (ya da undefined geçerse) varsayılan değer devreye girer:
Üç çağrı da çalışıyor. Birinci ve üçüncü varsayılanı devreye sokar, ikincisi ise verilen değeri kullanır. Bu ES6 ile gelen bir sözdizimi — 2015 öncesinde fonksiyon gövdesinin içinde name = name || "friend" yazmak zorundaydık ki bu da 0 ve "" gibi falsy değerlerde tatsız bug'lara yol açıyordu.
Varsayılan değer olarak sadece sabit (literal) değil, herhangi bir ifade de kullanabilirsin:
İfade, fonksiyon tanımlandığında bir kere değil, her çağrıda yeniden değerlendirilir. Yani Python'daki meşhur "mutable default" tuzağı burada yok — her çağrı taptaze bir new Date() alır.
Varsayılan değeri sadece undefined tetikler
Çoğu kişiyi şaşırtan kural tam olarak bu. Varsayılan değer yalnızca argüman undefined olduğunda devreye girer; falsy değerlerde devreye girmez ve null geçtiğinizde de girmez:
Sadece son çağrı "friend" değerini kullanıyor. null göndermek "bu değer null olsun" demektir — JavaScript de seni ciddiye alıp öyle kabul eder. Aynı şey boş string'ler ve sıfırlar için de geçerli: bunlar birer değerdir, eksik argüman değil.
null gelmesini "hiç değer verilmemiş" gibi ele almak istiyorsan, bunu kendin halletmelisin:
?? operatörü (nullish coalescing), hem null hem de undefined değerlerini "eksik" olarak kabul eder. Buna ileriki bir bölümde daha ayrıntılı değineceğiz.
Varsayılan değerler, önceki parametrelere referans verebilir
JavaScript'te parametreler soldan sağa doğru değerlendirilir. Yani sonraki bir parametrenin varsayılan değeri, kendisinden önce gelen herhangi bir parametreyi rahatlıkla kullanabilir:
Tek argümanla çağırdığınızda küp üretir. İki argüman verince kare prizma elde edersiniz. Burada sıra önemli — henüz tanımlanmamış bir parametreye referans veremezsiniz:
function bad(a = b, b = 1) {
return a + b;
}
bad(); // ReferenceError: Cannot access 'b' before initialization
let ile tanımlanan değişkenlerde olduğu gibi: tanımlanmadan önce kullanmak hatadır.
Default Parametreler ve Destructuring Birlikte
Parametreleri destructure ederken aynı anda varsayılan değer de atayabilirsiniz. Bu, "options object" şeklinde argüman alan fonksiyonlarda sıkça karşımıza çıkan bir kalıptır:
Burada iki katmanlı bir varsayılan değer yapısı var. İçteki varsayılanlar (role = "member", active = true) eksik kalan özellikleri tamamlıyor. Dıştaki = {} ise çağıran taraf hiç argüman göndermediği durumu karşılıyor — bu olmasaydı createUser() çağrısı undefined değerini destructure etmeye çalışır ve hata fırlatırdı.
İlk bakışta kalabalık duruyor ama bu kalıp modern JavaScript kod tabanlarında her yerde karşınıza çıkıyor. Gözünüz { ... } = {} yapısını "varsayılanlı seçenekler" olarak tanımaya başladığında artık akıcı şekilde okunuyor.
Ortadaki Argümanı Atlamak
JavaScript'te Python'daki gibi isimli (keyword) argümanlar yok. Ortadaki bir parametreyi atlayıp varsayılan değerini kullanmak istiyorsanız, o parametre yerine açıkça undefined geçmeniz gerekir:
prefix için undefined geçmek varsayılanı korur. Ama çirkin duruyor. Eğer çağrılarda sık sık undefined yazdığınızı fark ediyorsanız, bu bir options objesine geçmeniz gerektiğinin sinyalidir:
Artık çağıran kişi neyi geçersiz kılmak istediğini ismiyle belirtiyor ve sıra hiç önemli değil.
Varsayılan değerler length'e dahil edilmiyor
Çoğu zaman dert etmeyeceğiniz ama ara sıra kafa karıştıran ufak bir ayrıntı var. Bir fonksiyonun length özelliği, varsayılan değeri olan ilk parametreden önceki parametre sayısını verir:
Fonksiyonları inceleyen kütüphaneler (bazı test araçları ve DI kütüphaneleri gibi) "zorunlu" parametre sayısını bulmak için length değerini kullanır. Böyle bir kuralın var olduğunu bilmek iyi; ama bu tür bir araç geliştirmiyorsanız ezberlemeye değmez.
Sırada: Rest ve Spread
Varsayılan değerler, parametreleri önceden bildiğiniz durumlarda işinizi görür. Ama bazen bilemezsiniz — bir fonksiyonun kaç argüman alacağı belli değildir ya da gelen argümanları olduğu gibi başka bir fonksiyona iletmek istersiniz. İşte ...rest parametresi ve spread operatörü tam olarak bunun için var. Sırada onlar geliyor.
Sıkça Sorulan Sorular
JavaScript'te bir parametreye nasıl varsayılan değer atanır?
Fonksiyon imzasında parametre adının yanına = koyup varsayılan değeri yazmak yeterli: function greet(name = 'friend') { ... }. Çağıran taraf hiç değer göndermezse ya da açıkça undefined geçerse, varsayılan değer devreye girer. ES6 ile gelen bu sözdizimi artık tüm modern JavaScript ortamlarında sorunsuz çalışıyor.
Parametre ile argüman arasındaki fark nedir?
Parametreler, fonksiyon tanımındaki isimlerdir — function add(a, b) fonksiyonunun parametreleri a ve b'dir. Argümanlar ise fonksiyonu çağırırken gönderdiğiniz gerçek değerlerdir: add(2, 3) çağrısındaki argümanlar 2 ve 3. Bu ayrım özellikle hata mesajlarını ve dokümantasyonu okurken işinize yarar.
null gönderdiğimde varsayılan değer çalışır mı?
Hayır. Varsayılan değer yalnızca argüman undefined olduğunda (veya hiç gönderilmediğinde) devreye girer. null geçmek, "sana bir değer veriyorum ve o değer null" demektir — bu durumda varsayılan atlanır. null ile undefined'ı aynı kabul eden dillerden gelen geliştiricileri en çok yakalayan nokta tam da burası.
Bir parametrenin varsayılan değeri başka bir parametreye referans verebilir mi?
Evet. Parametreler soldan sağa değerlendirildiği için, sonraki bir parametrenin varsayılanı önceki parametreleri kullanabilir: function box(width, height = width). Varsayılan olarak fonksiyon çağrısı da yazabilirsiniz — function log(msg, time = Date.now()) — ve bu ifade her çağrıda yeniden çalışır.