Yücel Alkan

JavaScript Call ve Apply Fonksiyonlarının Kullanımı

Merhabalar. Bu yazımda JavaScript'te yer alan call ve apply fonksiyonlarının kullanımından bahsedeceğim. İkisinin de yaptığı iş aynıdır ancak kullanımlarında küçük bir fark bulunmaktadır. Bu nedenle ikisini bir arada anlatmak istedim. call ve apply fonksiyonları; bir objenin parametre olarak başka bir objeye gönderilmesini ve o objeye ait metotların çalıştırılmasını sağlayan yapılardır. Tanım biraz kafa karıştırıcı olabilir ancak aşağıdaki örneklerle anlayacağınızı düşünüyorum. 

Öncelikle call ve apply fonksiyonlarının kullanımına bakalım.

obje.call.metotAdi(obje2, parametre1, parametre2...)
obje.call.metotAdi(obje2, [parametre1, parametre2...])

Yukarıdaki örneklerden anlaşılacağı gibi call ve apply arasındaki fark şudur; call fonksiyonunda obje dışında parametre göndermek istiyorsanız araya virgül koyarak göndermeniz gerekiyor. Yani her bir parametre karşı tarafa tek tek gönderilmiş oluyor. Diğer bir fonksiyon olan apply'de ise parametreler dizi olarak gönderiliyor. 

Hemen bir örnekle call ve apply fonksiyonlarının kullanımına bakalım. Öncelikle iki farklı telefona ait bilgileri içeren huawei ve samsung objelerini oluşturuyorum. İlk oluşturacağım huawei objesi Huawei P30'a ait bilgileri içerecek.

var huawei = {
    marka: "Huawei",
    model: "P30",
    deger: 600,     // Dolar 
    onKamera: 8,
    arkaKamera: 48 
};

Şimdi de Samsung Galaxy A70'e ait bilgileri içerecek olan samsung objesini oluşturuyorum.

var samsung = {
    marka: "Samsung",
    model: "Galaxy A70",
    deger: 700,     // Dolar
    onKamera: 5,
    arkaKamera: 32
}

Bu şekilde istediğiniz kadar obje oluşturabilirsiniz. Şimdi telefon adında bir obje oluşturuyorum ve içerisine dört adet metot/fonksiyon ekliyorum. Bu metotlardan telefonAdi metodu, marka ve model birlikte olmak üzere telefonun tam adını döndürecek. Diğer metot olan tlFiyat metodu ise dolar olarak telefon değerini TL'ye çevirip döndürecek. Üçüncü metot olan kameraBilgileri metodu telefona ait kamera bilgilerini toplu halde döndürecek. Son olarak ise hafizaBilgileri metodu ise telefona ait geçerli hafızayı ve arttırılabilir maksimum hafızayı GB cinsinden döndürecek.

var telefon = {
    telefonAdi : function(){
        return this.marka + " " + this.model;
    },
    tlFiyat : function(){
        var dolarKuru = 5.70;
        return dolarKuru * this.deger + " TL";
    },
    kameraBilgileri : function(){
        return "Ön kamera : " + this.onKamera + " Arka Kamera : " + this.arkaKamera;
    },
    hafizaBilgileri : function(hafiza,maxHafiza){
        return "Telefon Hafızası :" + hafiza + " GB, Arttırılabilir Max Hafıza : " + maxHafiza + " GB";
    }
}

Dikkat ettiyseniz yukarıda tanımladığım telefon objesinde bilgi içeren herhangi bir alan yok. Aklınıza şu soru gelebilir; telefon nesnesi içinde bilgi yoksa buradaki this ifadeleri ne oluyor? Öyle ya this ifadesi o nesne içindeki alanlara erişimi sağlıyordu. Burada bilgi yoksa this'ler ne işe yarıyor.

İşte call ve apply tam olarak burada devreye giriyor zaten. Oluşturduğum samsung ve huawei nesnelerini, telefon adlı nesneye parametre olarak gönderip, telefon nesnesinde yer alan metotları, appyle ve call ile çalıştırmak mümkün. Yani telefon nesnesi, kendisine gelen samsung ve huawei parametrelerini miras alıp, sanki kendisi bu nesneymiş gibi davranıyor. İlgin değil mi?

Peki nasıl oluyor buna bir göz atalım.

telefon.telefonAdi.call(samsung)
telefon.telefonAdi.apply(samsung)

Bu ifadeler aslında şu anlama geliyor; telefon nesnesi içinde yer alan telefonAdi metodunu bul ve samsung nesnesini paramtre olarak çağır. Yukarıdaki iki ifade de bize "Samsung Galaxy A70" bilgisini verecektir.

Başka bir metodu çağıralım. Örneğin, tlFiyat metodunu çağırmak istersek;

console.log( telefon.tlFiyat.call(huawei) );
console.log( telefon.tlFiyat.call(samsung) );

Bu kodların çıktısı; 3420 TL ve 3990 TL olacaktır. Yani telefonlara ait dolar bilgisi, tlFiyat metodu içerisinde bugünkü dolar kuru olan 5.70 ile çarpılacak ve sonuna da TL ifadesi eklenerek elde edilen veri son aşamada döndürülecektir.

Tanımladığımız diğer metodu da çağıralım.

console.log( telefon.kameraBilgileri.call(huawei) );
console.log( telefon.kameraBilgileri.call(samsung) );

Bu kodların konsol çıktısı aşağıdaki gibi olacaktır.

Ön kamera : 8 Arka Kamera : 48
Ön kamera : 5 Arka Kamera : 32

Dikkat ettiyseniz buraya kadar call ve apply fonksiyonları arasında hem kullanım olarak hem de verdikleri çıktı olarak hiçbir fark yok. Şimdi gelelim aralarındaki ince farka.

Dikkat ettiyseniz, telefon nesnesi içerisinde bulunan hafizaBilgileri metodunu kullanmadık. Bu metoda iki tane parametre geliyor; hafiza ve maxHafiza. İyi de biz samsung ve huawei nesnelerini oluştururken hafıza bilgilerini saklamadık ki. İşte bu durumda call ve apply metotlarının parametreli olarak kullanılması mümkün.

Şimdi hem telefon nesnesine ait hafizaBilgileri adındaki metodu çalıştırmak istiyorum hem de telefona ait hafıza bilgilerini nesne ile birlikte parametre olarak göndermek istiyorum. Samsung Galaxy A70 telefonunun hafızası 128 GB, arttırılabilir maksimum hafıza ise 512 GB'mış. Şimdi bu iki değeri nesne ile birlikte parametre olarak göndeceğim.

console.log( telefon.hafizaBilgileri.call(samsung, 128, 512) );

Bu kodun ekran çıktısı aşağıdaki gibi olacaktır.

Telefon Hafızası :128 GB, Arttırılabilir Max Hafıza : 512 GB

Şimdi de huawei nesnesi için aynı metodu çağıralım. Huawei P30'un hafızası 64 GB, maksimum arttırılabilir hafıza ise 128 GB olsun. Bu bilgilere göre kullanım ve ekran çıktısı aşağıdaki gibi olacaktır.

console.log( telefon.hafizaBilgileri.call(huawei, 64, 128) );
Telefon Hafızası :64 GB, Arttırılabilir Max Hafıza : 128 GB

Yazımın giriş kısmında call ile apply arasındaki farkın, parametrelerin gönderim şeklinde olduğunu belirtmiştim. call metodunda bilgiler araya virgül konularak ayrı ayrı parametre olarak gönderilirken apply'de ise dizi olarak gönderiliyor. Yani yukarıdaki bilgilere göre apply fonksiyonunun kullanımı aşağıdaki gibi olacaktır.

console.log( telefon.hafizaBilgileri.apply(samsung, [128 , 512]) );
console.log( telefon.hafizaBilgileri.apply(huawei, [64 , 128]) );

Bu kodlar da call fonksiyonunda olduğu gibi aynı çıktıları verecektir. Sadece parametre olarak gönderilen bilgilerin dizi yapısında olduğuna dikkat etmeniz yeterli olacaktır. 

call ve apply fonksiyonlarının kullanımına ait olan yukarıdaki uygulamaları içeren dosyayı bu linkten indirebilirsiniz.

Soru, görüş ve önerilerinizi yorum olarak belirtebilirsiniz. Hayırlı çalışmalar dilerim. 

Yorumlar
Fateh (21 Nisan 2020 - 15:16)
Sonunda anladim. Tessekur edirem
Cevapla
Hibrit Usta (15 Ocak 2021 - 00:25)
Emeğinize sağlık.
Cevapla
Murat (23 Haziran 2021 - 08:14)
film gibi izledim sonucu görmek için, tşrklr.
Cevapla
Turan Abdurahmanova (26 Haziran 2021 - 08:24)
Çox sağolunnnn
Cevapla
Yorum Yapın