Ders 14 / 21
Parametreler
Eksik ve fazla argümanlar, varsayılan değerlerin devreye girme koşulu, kalan parametreler ve yayma, argüman nesnesi ve yapıbozumlu parametreler.
İçindekiler
Önceki derste fonksiyonlar sabit sayıda argümanla çağrıldı. JavaScript bu konuda gevşektir: eksik argüman hata vermez, fazla argüman da vermez. Gevşekliğin bedeli, eksikliğin sessiz kalmasıdır.
Bu ders parametre kurallarını ele alır. Programlama Temelleri kursundaki Değer ve Referans ile Aktarım dersinde parametre–argüman ayrımı ve değişken sayıda argüman kavramı kurulmuştu; burada JavaScript’in bu kavramları hangi sözdizimiyle karşıladığı ve hangi tuzakları taşıdığı gösterilecek.
Eksik ve Fazla Argüman
Çağrıda verilmeyen parametre undefined değerini alır. Fazla verilen argüman sessizce
yok sayılır:
function rapor(istasyon, esik) { return `${istasyon} / ${esik}`; } console.log(rapor("A1")); console.log(rapor("A1", 20, "fazla"));
A1 / undefined A1 / 20
İki davranış da hata üretmedi. Bu, dilin bilinçli bir kararıdır ve fonksiyonların
argüman sayısına göre farklı davranmasını mümkün kılar. Bedeli, yazım hatasıyla eksik
kalan bir argümanın ancak undefined bir değer taşıyıp ilerideki bir işlemi bozduğunda
fark edilmesidir.
Varsayılan Değerler
Parametreye varsayılan değer verilebilir. Varsayılan yalnızca argüman undefined
olduğunda devreye girer — eksik olduğunda ya da açıkça undefined verildiğinde.
function rapor(istasyon, esik = 20) { return `${istasyon} / ${esik}`; } console.log(rapor("A1")); console.log(rapor("A1", undefined)); console.log(rapor("A1", null)); console.log(rapor("A1", 0)); console.log(rapor.length);
A1 / 20 A1 / 20 A1 / null A1 / 0 1
Üçüncü ve dördüncü satırlar, Doğruluk Değerleri dersindeki ?? işlecinin ölçütünden de
dar bir ölçüt olduğunu gösteriyor: null bile varsayılanı tetiklemez. 0 değeri de
geçer — varsayılan değerler, || ile yazılmış yedek atamalarının bozduğu durumu doğal
olarak korur.
Son satır, length özelliğinin varsayılan değerli parametreden önceki parametre
sayısını verdiğini gösteriyor.
Varsayılan ifadeler her çağrıda yeniden değerlendirilir ve kendilerinden önceki parametreleri kullanabilir:
let sayac = 0; function sonraki() { sayac += 1; return sayac; } function etiketle(ad, sira = sonraki()) { return `${ad}-${sira}`; } console.log(etiketle("A1")); console.log(etiketle("A2")); console.log(etiketle("B1", 99)); console.log(etiketle("B2"));
A1-1 A2-2 B1-99 B2-3
Üçüncü çağrıda argüman verildiği için sonraki hiç çağrılmadı; sayaç artmadı. Bu,
varsayılanın çağrı anında ve yalnızca gerektiğinde değerlendirildiğinin kanıtıdır.
Önceki parametreye dayanan varsayılan, aralık tanımlarında kullanışlıdır:
function aralik(alt, ust = alt + 5) { return [alt, ust]; } console.log(aralik(18)); console.log(aralik(18, 30));
[ 18, 23 ] [ 18, 30 ]
Sıra tek yönlüdür: bir parametre yalnızca kendisinden önce yazılmış parametrelere başvurabilir.
Varsayılan ifadenin çağrı anında değerlendirilmesi, zorunlu parametreleri bildirmenin de yolunu açar:
function zorunlu(ad) { throw new Error(`${ad} parametresi zorunlu`); } function kaydet(istasyon = zorunlu("istasyon"), sicaklik = zorunlu("sicaklik")) { return `${istasyon}=${sicaklik}`; } console.log(kaydet("A1", 21.5)); try { kaydet("A1"); } catch (hata) { console.log(hata.name + ": " + hata.message); }
A1=21.5 Error: sicaklik parametresi zorunlu
Argüman verildiğinde varsayılan ifade hiç çalışmaz; verilmediğinde hata fırlatılır.
Hata nesneleri ve throw deyimi bu konunun son dersinde ele alınacak.
Kalan Parametreler ve Yayma
Sayısı önceden bilinmeyen argümanlar kalan parametre (rest parameter) ile toplanır. Üç noktalı yazım, kalan tüm argümanları gerçek bir diziye koyar:
function enYuksek(etiket, ...okumalar) { return `${etiket}: ${Math.max(...okumalar)} (${okumalar.length} okuma)`; } console.log(enYuksek("A1", 21.5, 19.75, 23)); console.log(enYuksek("B1")); console.log(enYuksek.length);
A1: 23 (3 okuma) B1: -Infinity (0 okuma) 1
İkinci satır bir sınır durumunu gösteriyor: argümansız çağrıda okumalar boş dizidir ve
Math.max() çağrısı -Infinity verir. Bu, matematiksel olarak tutarlıdır — boş kümenin
en büyük elemanı için nötr eleman döner — ama ölçüm bağlamında anlamsızdır. Boş liste
denetimi yazılmalıdır.
Aynı üç nokta, çağrı tarafında ters yönde çalışır: bir diziyi ayrı argümanlara açar.
function enYuksek(etiket, ...okumalar) { return `${etiket}: ${Math.max(...okumalar)}`; } const sicakliklar = [21.5, 19.75, 23, 18.25]; console.log(enYuksek("hepsi", ...sicakliklar));
hepsi: 23
İki kullanım karıştırılmamalıdır. Parametre listesindeki üç nokta toplar; çağrıdaki üç nokta dağıtır. Aynı sözdiziminin iki yönü, bulunduğu yere göre ayrılır.
Kalan parametre yalnızca son sırada bulunabilir ve length özelliğine sayılmaz.
Argüman Nesnesi
Kalan parametrelerden önce, değişken sayıda argüman arguments adlı örtük bir nesneyle
okunurdu. Bu nesne hâlâ bulunur ve eski kodda karşılaşılır:
function eskiBicim() { console.log(typeof arguments, arguments.length); console.log(Array.isArray(arguments)); console.log(Array.from(arguments)); } eskiBicim(21.5, 19.75);
object 2 false [ 21.5, 19.75 ]
İkinci satır sorunun kendisidir: arguments bir dizi değildir. Uzunluğu ve dizinleri
vardır, ama dizi yöntemleri yoktur; kullanmak için önce diziye çevrilmesi gerekir.
İkinci sorun varsayılan değerlerle ortaya çıkar:
function varsayilanli(a = 1) { console.log("arguments.length:", arguments.length, "a:", a); } varsayilanli(); varsayilanli(5);
arguments.length: 0 a: 1 arguments.length: 1 a: 5
arguments yalnızca gerçekten verilen argümanları sayar; varsayılanla dolan
parametreyi görmez. İki bilgi kaynağı ayrışır ve hangisinin okunacağı belirsizleşir.
Üçüncü olarak, arguments ok fonksiyonlarında hiç bulunmaz — bir sonraki dersin konusu.
Kursta değişken sayıda argüman her zaman kalan parametreyle yazılacaktır.
Yapıbozumlu Parametreler
Üç dörtten fazla parametre alan bir fonksiyonda çağrı satırı okunmaz hale gelir: sıra ezberlenmelidir. Çözüm, seçenekleri bir nesnede toplayıp parametre listesinde yapıbozumla (destructuring) açmaktır:
function ozet({ istasyon, sicaklik, birim = "C" }) { return `${istasyon}: ${sicaklik} ${birim}`; } console.log(ozet({ istasyon: "A1", sicaklik: 21.5 })); console.log(ozet({ istasyon: "A2", sicaklik: 19.75, birim: "K" }));
A1: 21.5 C A2: 19.75 K
Çağrı satırı artık hangi değerin ne olduğunu kendisi söylüyor ve sıra önemsiz hale geldi. Varsayılanlar tek tek alanlara verilebiliyor.
Bu yazımın bir tuzağı vardır: argüman hiç verilmezse yapıbozum undefined üzerinde
çalışmaya kalkar:
function ozet({ istasyon, sicaklik }) { return `${istasyon}: ${sicaklik}`; } try { console.log(ozet()); } catch (hata) { console.log(hata.name + ": " + hata.message); }
TypeError: Cannot destructure property 'istasyon' of 'undefined' as it is undefined.
Çözüm, parametrenin tamamına boş nesne varsayılanı vermektir:
function ozetGuvenli({ istasyon = "?", sicaklik = null } = {}) { return `${istasyon}: ${sicaklik}`; } console.log(ozetGuvenli()); console.log(ozetGuvenli({ istasyon: "B1" }));
?: null B1: null
İki varsayılan katmanı birlikte çalışıyor: dıştaki = {} nesnenin kendisi eksikse,
içtekiler tek tek alanlar eksikse devreye giriyor.
Fonksiyonun tüm seçenekleri zorunluysa dıştaki varsayılan yazılmaz; o zaman eksik çağrı hata verir ve bu istenen davranıştır. Seçim, sözleşmenin ne olduğuna bağlıdır.
Özet
- Eksik argüman
undefinedolur, fazla argüman yok sayılır; ikisi de hata üretmez. - Varsayılan değer yalnızca argüman
undefinediken devreye girer;nullve0varsayılanı tetiklemez. - Varsayılan ifadeler her çağrıda ve yalnızca gerektiğinde değerlendirilir; kendilerinden önceki parametreleri kullanabilirler.
- Kalan parametre argümanları gerçek bir dizide toplar ve son sırada bulunur; çağrıdaki üç nokta ters yönde, diziyi argümanlara dağıtır.
argumentsnesnesi dizi değildir ve varsayılanla dolan parametreleri saymaz; kursta kalan parametre kullanılır.- Yapıbozumlu parametre adlandırılmış seçenek sağlar; nesnenin tamamına varsayılan verilmezse argümansız çağrı hata verir.
Sonraki Adım
Bu derste geçen (d) => d > esik gibi kısa yazımlar açıklanmadan kullanıldı. Sonraki
ders ok fonksiyonlarını ele alacak: kısa sözdiziminin biçimleri, örtük dönüş kuralı ve
bu fonksiyonların arguments nesnesi ile bağlam davranışındaki farkı. Fark yalnızca
kısalık değildir; ok fonksiyonu bazı yerlerde kullanılamaz.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.