Javascript — Call,Apply ve Bind Fonksiyonları

Mustafa Murat Coşkun
Yazılım Bilimi
Published in
3 min readSep 13, 2018

Bu yazımda Javascriptteki call,apply ve bind fonksiyonlarını göstermeye çalışacağım. Yazıya başlamadan önce Javascriptteki Prototype mantığını ve this anahtar kelimesini iyice öğrenmenizi tavsiye ediyorum.

Javascript her ne kadar oldukça esnek bir dil olsa da, bazı zamanlar karın ağrısı çektiğimiz bir dil haline gelebiliyor. Javascript ile geliştirmeye yeni başlayanlar da ilk zamanlarda this anahtar kelimesinin kapsam alanını(scope) karıştırarak kodlarında sıkıntıya düşebiliyorlar. Şimdi ilk olarak, call,apply ve bind fonksiyonlarını göstermeden önce bir örnek ile this anahtar kelimesini hatırlatmak istiyorum.

Örneğin aşağıdaki gibi bir kod parçasında this bize global scopetaki(global kapsam) window objesini vermektedir. Çünkü Javascriptte global scopetaki objemiz window objesidir.

Ancak her zaman this anahtar kelimesi bizim window objemizi göstermez. Şu örneğimize de bakalım.

Burada da Person constructorının içinde olduğumuz için Person objesi sonucunu aldık.

Ancak daha önceden söylediğim gibi, this anahtar kelimesinin bazı durumlarda kullanımı ve hangi objeyi gösterdiğini anlamak her zaman bu kadar kolay olmaz. Böyle durumlarda veya bir fonksiyonu farklı objeler üzerinde kullanmak istediğimiz zamanlarda, Javascript prototype objesinin içinde bulunan call,apply ve bind fonksiyonlarını kullanabiliriz.

Call ve Apply

Call ve Apply fonksiyonları Function objemizin __proto__ objesinde bulunan iki adet fonksiyondur. Bu fonksiyonların görevleri aynı olsa da kullanımları arasında ufak bir fark vardır. Şimdi ilk olarak Mozilla’nın dokümanlarından bu fonksiyonların ne iş yaptığını anlamaya çalışalım.

Call() fonksiyonu, verilen this anahtar değeriyle(obje) ve bağımsız olarak sağlanan bağımsız argümanlarla bir fonksiyonu çağırır. Argümanlar fonksiyona tek tek gönderilir. (Örnek: test(obj,arg1,arg2,arg3))

Apply() fonksiyonu, verilen this anahtar değeriyle(obje) ve bağımsız olarak sağlanan değişkenlerle bir fonksiyonu çağırır. Argümanlar fonksiyona argüman listesi şeklinde gönderilir. (Örnek: test(obj,[arg1,arg2,arg3]))

Bu fonksiyonların ne yaptığını anlamak için şu örneğimize bakalım.

Buradaki çıktının neden NaN olduğuyla ilgili bir fikri olan var mı ? Fikri olmayanlar için açıklamak gerekirse, şu anda global scope’ta bulunan objemiz window objesi olduğu için ve this anahtar kelimesi bu objeyi gösterdiği için bu sonucu aldık. Window objesinin içinde number1 veya number2 şeklinde property bulunmuyor. Bu nedenle aslında “undefined + undefined + 100” gibi bir toplama yapıyoruz ve bunun sonucunda “NaN” sonucunu elde ediyoruz.

Peki bu örnekte addNumbers fonksiyonunun hem obj1 hem de obj2 objesi için çalışmasını istersek ne yapabiliriz ? İşte burada yardımımıza call ve apply fonksiyonları koşuyor. Burada, yukarıdaki tanımlara göre call veya apply fonksiyonlarını kullanırsak this anahtar kelimesi, call fonksiyonuna hangi objeyi argüman olarak gönderirsek onu gösterecektir.

Burada call metoduna birinci argüman olarak obj1'i gönderdiğimizde this anahtar kelimesi bu objeyi gösterdiği için sonucumuz 130 çıktı. Aynı şekilde, obj2'i gönderdiğimizde de 180 sonucunu aldık.Yani, bir fonksiyonu call fonksiyonuyla farklı objeler ile kullanabildik. Şimdi de bu kullanımı apply metoduyla yapmaya çalışalım.

Peki biz bu fonksiyonları nerelerde kullanabiliriz ? Örneğin, Prototype tabanlı kalıtım yaparken bu fonksiyonlar oldukça yararlı olacaktır.

Burada ES6 sınıflarında kullandığımız super() gibi, Person yapıcı metodunu call fonksiyonu sayesinde kendi objemizin yapıcı metodu içinde çağırabiliriz.

Bind Fonksiyonu

Bind fonksiyonu da mantık olarak call ve apply fonksiyonlarına oldukça fazla benzer. Ancak kullanım olarak bu fonksiyonlardan farklıdır. Aşağıda kendi yaptığım tanımı görebilirsiniz.

Bind() fonksiyonu, içine verilen objeye göre yeni bir fonksiyon kopyası yaratır. Oluşan bu kopya fonksiyonu daha sonradan argüman listesi ile beraber gönderilen objeye kullanabiliriz.

Hiçbir şey anlamadık değil mi ? Anlamak için örneğimize bakalım.

Burada da bind fonksiyonunun kullanımını görüyoruz. Aslında mantık olarak call ve apply’a benzese de yapı olarak epey farklı. Call ve Apply fonksiyonları bir fonksiyonu hemen çalıştırırken, bind fonksiyonu bize yeni bir kopya üretmektedir. Oluşturulan bu kopyayı ise istediğimiz herhangi bir bağlamda(context) kullanabiliriz.

Aklınızda şu şekilde bir sorunun döndüğünü tahmin ediyorum.

“Bind, Call ve Apply mantık olarak aynıysa hangisini nerelerde kullanacağım ?”

Javascript’e yeni başlayanların bu soruyu sorması oldukça normal. Cevabını şu şekilde verebiliriz.

Bind fonksiyonundan, fonksiyonumuzu başka bir bağlamda daha sonradan kullanabilmek adına yararlanabiliriz (örnek,Javascript Olayları — JS Events). Call ve Apply Fonksiyonlarını ise bir fonksiyonu hemen bir obje ile çağırmak için kullanabiliriz.

Bu söylediklerim sizin için biraz havada kalabilir. Ancak bu fonksiyonları Javascriptte ilerledikçe nerelerde kullanabileceğinizi çok daha iyi bir şekilde anlayacaksınız.

Bu gönderi hakkında eklemek ve düzeltmek istediğiniz noktalar var ise yorumlarınızla gönderiyi güçlendirebiliriz.

--

--

Mustafa Murat Coşkun
Yazılım Bilimi

MsC — Computer Engineering — METU — Founder Of Yazılım Bilimi | Instagram : @mustafamuratcoskunn