Ders 15 / 21
Ok Fonksiyonları
Kısa sözdiziminin biçimleri, örtük dönüş ve nesne döndürme tuzağı, argüman nesnesinin bulunmaması ve bağlamın çevreleyen kapsamdan gelmesi.
İçindekiler
Önceki derslerde (d) => d > esik gibi yazımlar açıklanmadan kullanıldı. Bu ders o
sözdizimini tanımlar. Ok fonksiyonu üçüncü bir fonksiyon tanımlama biçimidir ve iki
kazanım sunar: kısalık ve bağlam davranışının değişmesi.
İkincisi asıl olandır. Kısalık okunaklılığı bazen artırır bazen azaltır; bağlam davranışı ise ok fonksiyonunun bazı yerlerde kullanılamamasına yol açar. Bu dersin sonunda hangi biçimin nerede seçileceği bir kurala bağlanacak.
Sözdizimi Biçimleri
Ok fonksiyonu, parametre listesi ve gövdeden oluşur; ikisi => ile ayrılır.
const kare = (x) => x * x; const tekParam = x => x * 2; const iki = (a, b) => a + b; const sifir = () => 42; const govdeli = (dizi) => { let t = 0; for (const d of dizi) t += d; return t; }; console.log(kare(4), tekParam(4), iki(1, 2), sifir()); console.log(govdeli([21.5, 19.75]));
16 8 3 42 41.25
Tek parametrede parantez atlanabilir; parametresiz ve çok parametreli biçimlerde zorunludur. Kursta parantez her zaman yazılacaktır — tek biçimlilik, parametre eklendiğinde yapılacak değişikliği azaltır.
Gövde iki türlüdür. Süslü ayraçsız gövde bir ifadedir ve değeri örtük olarak
döndürülür; return yazılmaz. Süslü ayraçlı gövde bir bloktur ve dönüş açıkça
yazılır. govdeli fonksiyonunda return olmasaydı sonuç undefined olurdu.
Nesne Döndürme Tuzağı
Örtük dönüşle nesne döndürmek, sözdiziminde bir belirsizlik yaratır: açılan süslü ayraç nesne mi, blok mu?
const hatali = (ad) => { istasyon: ad }; console.log(hatali("A1"));
undefined
Ayrıştırıcı süslü ayracı blok olarak okudu. Blok içindeki istasyon: ad satırı bir
nesne özelliği değil, istasyon etiketli bir deyimdir — Döngüler dersindeki etiketli
döngü sözdiziminin aynısı. Blokta return bulunmadığı için sonuç undefined oldu. Hata
verilmedi.
Çözüm, nesneyi parantez içine almaktır:
const nesneDonen = (ad) => ({ istasyon: ad }); console.log(nesneDonen("A1"));
{ istasyon: 'A1' }
Parantez, süslü ayracın bir ifade bağlamında olduğunu belirtir; ayrıştırıcı artık nesne okur.
Argüman Nesnesi Bulunmaz
Ok fonksiyonlarının kendi arguments nesnesi yoktur:
const okFn = () => { try { return arguments.length; } catch (hata) { return hata.name + ": " + hata.message; } }; console.log(okFn(1, 2));
ReferenceError: arguments is not defined
İleti “bulunamadı” diyor; ok fonksiyonu böyle bir ad tanımlamıyor. Değişken sayıda argüman kalan parametreyle alınır:
const kalanIle = (...args) => args.length; console.log(kalanIle(1, 2));
2
Parametreler dersinde konan kural burada zorunlu hale geliyor.
Bağlam Çevreleyen Kapsamdan Gelir
Ok fonksiyonlarının kendi this bağlaması yoktur. Gövdedeki this, fonksiyonun
tanımlandığı yerdeki this değeridir. Adlandırma ve Kapsam Kuralları dersinde
kurulan sözcüksel kapsam ilkesi, ok fonksiyonlarında bağlama da uygulanır.
this bağlanmasının kuralları bir sonraki kursun konusudur. Burada yalnızca gözlemlenen
fark ele alınıyor ve bu fark en çok geri çağrı fonksiyonlarında görülür:
const izleyici = { esik: 20, sicakliklar: [21.5, 19.75, 23], klasikGeriCagri() { try { return this.sicakliklar.filter(function (d) { return d > this.esik; }); } catch (hata) { return hata.name + ": " + hata.message; } }, okGeriCagri() { return this.sicakliklar.filter((d) => d > this.esik); }, }; console.log(izleyici.klasikGeriCagri()); console.log(izleyici.okGeriCagri());
TypeError: Cannot read properties of undefined (reading 'esik') [ 21.5, 23 ]
İki yöntem de aynı nesnenin üzerinden çağrıldı ve dış this her ikisinde de nesnenin
kendisiydi. Fark iç fonksiyondadır. Klasik fonksiyon ifadesi kendi this bağlamasını
kurar; katı kipte bu bağlama undefined olur ve özellik okuma hata verir. Ok fonksiyonu
kendi bağlamasını kurmaz, dıştakini kullanır ve süzgeç beklendiği gibi çalışır.
Aynı davranış ters yönde de sonuç doğurur. Ok fonksiyonu bir nesne yöntemi olarak
yazıldığında, this nesneye bağlanmaz:
const istasyon = { ad: "A1", klasikYontem() { return this === undefined ? "this: undefined" : `this.ad: ${this.ad}`; }, okYontem: () => { return this === undefined ? "this: undefined" : `this.ad: ${this.ad}`; }, }; console.log(istasyon.klasikYontem()); console.log(istasyon.okYontem());
this.ad: A1 this: undefined
Ok fonksiyonu, tanımlandığı yerin this değerini aldı. Bu örnek bir modül dosyasında
çalıştırıldığı için en dış this değeri undefined’dır — Kod Çalıştırma Yolları
dersinde gösterilen modül kuralı. Betik kipinde aynı satır farklı bir değer verirdi; her
iki durumda da nesnenin kendisi olmazdı.
Kural buradan çıkar: nesne yöntemleri ok fonksiyonuyla yazılmaz.
Yapıcı Olarak Kullanılamaz
Ok fonksiyonları new ile çağrılamaz:
const Olcum = (ad) => { this.ad = ad; }; try { new Olcum("A1"); } catch (hata) { console.log(hata.name + ": " + hata.message); } function KlasikOlcum(ad) { this.ad = ad; } console.log(new KlasikOlcum("A1").ad); console.log(typeof Olcum.prototype, typeof KlasikOlcum.prototype);
TypeError: Olcum is not a constructor A1 undefined object
Son satır nedeni gösteriyor: ok fonksiyonunun prototype özelliği yoktur. Yapıcı
çağrısının bu özelliğe neden ihtiyaç duyduğu ve prototip zincirinin nasıl kurulduğu bir
sonraki kursun konusudur.
Biçim Seçimi
Üç tanım biçimi arasındaki seçim şu kurallara bağlanır:
- Bildirim: en dış kapsamdaki adlandırılmış yardımcı fonksiyonlar. Yukarı taşındığı için dosyadaki sıra serbesttir.
- Ok fonksiyonu: başka bir fonksiyona geçirilen kısa geri çağrılar ve çevreleyen bağlamı kullanması gereken iç fonksiyonlar.
- Klasik fonksiyon ifadesi: nesne yöntemleri ve
thisbağlamasının çağrı yerine göre belirlenmesi istenen durumlar.
Ok fonksiyonu her yerde kısa değildir. Gövdesi birkaç satırı geçen ve tek başına anlam taşıyan bir işlem, adlandırılmış bir bildirime çıkarıldığında hem okunur hem yeniden kullanılabilir olur.
Ölçüm Betiğine Uygulama
Dönüşüm zincirleri ok fonksiyonlarının en uygun kullanım alanıdır:
const kayitlar = [ { istasyon: "A1", sicaklik: 21.5 }, { istasyon: "A2", sicaklik: NaN }, { istasyon: "B1", sicaklik: 23 }, { istasyon: "B2", sicaklik: 18.25 }, ]; const ESIK = 20; const gecerli = (kayit) => !Number.isNaN(kayit.sicaklik); const esikUstu = (kayit) => kayit.sicaklik > ESIK; const etiketle = (kayit) => `${kayit.istasyon}=${kayit.sicaklik}`; console.log(kayitlar.filter(gecerli).filter(esikUstu).map(etiketle)); console.log( kayitlar .filter((k) => !Number.isNaN(k.sicaklik)) .map((k) => ({ ...k, sapma: k.sicaklik - ESIK })), );
[ 'A1=21.5', 'B1=23' ]
[
{ istasyon: 'A1', sicaklik: 21.5, sapma: 1.5 },
{ istasyon: 'B1', sicaklik: 23, sapma: 3 },
{ istasyon: 'B2', sicaklik: 18.25, sapma: -1.75 }
]
İki yazım da aynı ailedendir. Birincide süzgeçler adlandırıldı ve zincir okunur kaldı; ikincide kısa geri çağrılar yerinde yazıldı. İkinci çıktıda nesne döndürüldüğü için parantez zorunluydu — bu dersin ikinci bölümündeki tuzak.
İkinci çıktıdaki çok satırlı gösterim, çalışma zamanının inceleme biçimidir; dizi belirli bir uzunluğu aştığında satırlara bölünür. Bu biçim standartta tanımlı değildir ve ortamlar arasında değişir.
Nesne yayma sözdizimi ({ ...k }) burada kullanıldı ve Nesneler dersinde tanımlanacak.
Özet
- Ok fonksiyonunda tek parametrede parantez atlanabilir; süslü ayraçsız gövde ifadedir ve değeri örtük döndürülür.
- Örtük dönüşle nesne döndürmek için nesne parantez içine alınır; alınmazsa süslü ayraç
blok olarak ayrıştırılır ve sonuç
undefinedolur. - Ok fonksiyonlarının
argumentsnesnesi yoktur; değişken argüman kalan parametreyle alınır. - Ok fonksiyonunun
thisdeğeri tanımlandığı kapsamdan gelir; bu, geri çağrılarda istenen davranıştır, nesne yöntemlerinde istenmeyen davranıştır. - Ok fonksiyonları
newile çağrılamaz;prototypeözellikleri yoktur.
Sonraki Adım
Bu konudaki örneklerde hata durumları try/catch ile yakalandı ama yapı hiç
tanımlanmadı. Sonraki ders hata yönetimini ele alacak: try/catch/finally bloklarının
akışı, throw deyimi, yerleşik hata tipleri ve kendi hata tipini tanımlama. Ölçüm
betiğinin bozuk veriye verdiği yanıt da orada bir sözleşmeye bağlanacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.