- Konu sahibi
- #1
JavaScript'te this nedir?
JavaScript'te
this, kodun yazıldığı dosyayı değil, ilgili fonksiyonun nasıl çağrıldığını temel alarak o çağrıdaki this bağını temsil eden özel anahtar kelimedir. Değer bir nesne, ilkel değer veya undefined olabilir. Bu nedenle this değerini anlamanın en güvenilir yolu, fonksiyon tanımına değil çağrı biçimine bakmaktır. Ok fonksiyonları (=>) bu kuralın istisnasıdır; kendi this değerlerini oluşturmaz, dış kapsamdaki değeri kullanır.Çağrı biçimine göre this
Bir fonksiyonun
this değeri genellikle şu kurallardan biriyle belirlenir:- Bir nesnenin metodu olarak çağrılırsa
this, noktadan önceki nesnedir. - Normal fonksiyon olarak çağrılırsa katı modda (
"use strict")undefinedolur. Katı mod dışında tarayıcı davranışı farklı olabilir; bu nedenle buna güvenilmemelidir. newile çağrılırsa yeni oluşturulan nesnethisolur.call,applyveyabindile çağrılırsa kullanılacak nesne açıkça seçilir.- Ok fonksiyonunda
this, fonksiyonun tanımlandığı dış kapsamdan gelir vecall,applyveyabindile değiştirilemez.
En temel örnek şöyledir:
Kod:
"use strict";
const kullanici = {
ad: "Ayşe",
selamla() {
return `Merhaba, ben ${this.ad}`;
}
};
console.log(kullanici.selamla());
// Merhaba, ben Ayşe
Burada
selamla() nesnenin metodu olarak çağrıldığı için this, kullanici nesnesidir. Metodu ayrı bir değişkene aktarırsanız çağrı biçimi değişir:
Kod:
const selam = kullanici.selamla;
console.log(selam());
// Katı modda: TypeError veya undefined temelli hata
Bu hata,
this değerinin fonksiyonla birlikte kalıcı olarak taşınmadığını gösterir. Metodu nesneye bağlı tutmak için bind kullanabilirsiniz:
Kod:
const bagliSelam = kullanici.selamla.bind(kullanici);
console.log(bagliSelam());
// Merhaba, ben Ayşe
| Durum | Yaklaşım | this bağı |
|---|---|---|
| Nesne metodu | nesne.metot() | Çağrının alıcı nesnesi |
| Dış bağlama erişen callback | Ok fonksiyonu | Tanımlandığı dış kapsam |
| Metodu başka yere aktarma | bind | Önceden bağlanan değer |
| Kurucu çağrısı | new Kurucu() | Oluşturulan örnek |
| Açık bağlamlı tek çağrı | call / apply | Normal fonksiyonda verilen değer |
Normal fonksiyon ve ok fonksiyonu farkı
Aşağıdaki iki yöntem aynı şekilde davranmaz:
Kod:
const sayaç = {
deger: 0,
normal: function () {
setTimeout(function () {
console.log(this.deger);
}, 0);
},
ok: function () {
setTimeout(() => {
console.log(this.deger);
}, 0);
}
};
sayaç.normal(); // Normal iç fonksiyonun çağrı bağlamına göre undefined olabilir
sayaç.ok(); // 0
Ok fonksiyonu dıştaki
ok metodunun this değerini korur. Ancak bir fonksiyonu nesne metodu yapma amacı varsa ok fonksiyonu kullanmak genellikle doğru seçim değildir:
Kod:
const nesne = {
ad: "Deniz",
yaz: () => this.ad
};
Bu örnekte ok fonksiyonu
nesne nesnesini this olarak almaz. Nesne metodu için kısa yöntem veya normal fonksiyon kullanın.Hangi durumda hangi yöntemi kullanmalı?
Karar verirken önce fonksiyonun nasıl çağrılacağını yazın. Bir olay dinleyicisinde veya zamanlayıcıda dış nesnenin özelliklerine erişmeniz gerekiyorsa çoğu durumda ok fonksiyonu pratik çözümdür. Bir metodu başka bir bileşene, geri çağırıma veya değişkene aktaracaksanız
bind ile bağlamı açıkça sabitleyin.Sık yapılan hatalar
Değişken adına bakarak karar vermek:
const fn = nesne.metot atamasından sonra fn() çağrısı artık nesne metodu çağrısı değildir.Ok fonksiyonunda
this değiştirmeye çalışmak: bind kullanmak ok fonksiyonunun kendi bağlamını değiştirmez. Gerekirse normal fonksiyon kullanın.Her fonksiyonda
this beklemek: Bir fonksiyon nesneyle ilişkilendirilmemişse gerekli veriyi parametre olarak geçirmek çoğu zaman daha anlaşılırdır.İlk çözüm olarak
bind eklemek: Önce çağrının neden bağlam kaybettiğini belirleyin. Sorun zamanlayıcı veya geri çağırım içindeyse ok fonksiyonu, kalıcı bir metot referansı gerekiyorsa bind tercih edilebilir.Sık sorulan sorular
Bir fonksiyonun this değerini nasıl kontrol ederim?
Fonksiyonun çağrıldığı satıra bakın; gerekirse geçici olarak
console.log(this) ekleyin. Özellikle metodu değişkene aktarma ve geri çağırım içindeki çağrı biçimlerini inceleyin.call ile apply arasındaki fark nedir?
İkisi de
this değerini açıkça belirler. call argümanları ayrı ayrı, apply ise dizi benzeri tek bir koleksiyon olarak iletir. Yeni kodda yalnızca argüman biçimine göre seçim yapılır.Sınıflarda this neyi gösterir?
Sınıf metodunu nesne örneği üzerinden çağırdığınızda
this o örneği gösterir. Metodu ayırıp başka yerde çağıracaksanız bağlamı ayrıca korumanız gerekir.