Fonksiyon, İsim Verilmiş Bir Adım Bloğudur
Bir mantık parçasına isim verip tekrar tekrar kullanmak istediğinizde, bunu bir fonksiyonla yaparsınız. JavaScript'te bunun en eski ve en dolaysız yolu function declaration, yani function anahtar kelimesinin ardından bir isim yazmaktır.
Soldan sağa okuyalım:
function, bir fonksiyon tanımlamaya başlayan anahtar kelimedir.greet, fonksiyonun adıdır.(name), parametre listesidir — fonksiyonun aldığı girdiler.- Süslü parantezler içindeki blok ise fonksiyonun gövdesidir.
greet("Ada")bir çağrıdır. JavaScript,nameparametresine"Ada"değerini bağlayarak gövdeyi çalıştırır.
Fonksiyonu tanımlamak onu çalıştırmaz. Çalıştırmak için çağırman gerekir.
Parametreler ve Argümanlar
Parametre, fonksiyon tanımının içinde yazılan isimdir. Argüman ise fonksiyonu çağırırken aktardığın gerçek değerdir. Günlük konuşmada ikisi birbirinin yerine kullanılıyor; ama hata mesajlarını okurken bu ayrım işine yarar.
Burada base ve exponent birer parametre. 2 ve 10 ise argüman. JavaScript bunları sırayla eşleştirir: ilk argüman ilk parametreye, sonraki sonrakine, böyle gider.
Bazı dillerin aksine JavaScript, yanlış sayıda argüman gönderdiğinde şikayet etmez. Eksik kalanlar undefined olur, fazlalıklar ise sessizce yok sayılır. Bu esneklik bazen işe yarar, bazen de başınızı ağrıtır — varsayılan değerler ve rest parametrelerini ileriki yazılarda ele alacağız.
return ile Değer Döndürme
console.log ekrana yazı basar. return ise bir değeri çağıran tarafa geri verir, böylece o değer kullanılabilir:
return olmadan fonksiyon undefined döner:
return aynı zamanda fonksiyondan anında çıkar. Erken return kullanımı, asıl mantığa girmeden önce uç durumlardan sıyrılmanın standart yoludur:
Erken return'ler sayesinde fonksiyonun gövdesi iç içe geçmiş bir if/else piramidine dönüşmez.
Hoisting: Tanımlamadan Önce Çağırabilirsin
Başka dillerden gelenleri gerçekten şaşırtan bir konu var. Function declaration'lar hoist edilir — yani JavaScript, kod çalışmaya başlamadan önce bunları kendi kapsamlarının en üstüne taşır. Bu da demek oluyor ki, bir fonksiyonu daha tanımlanmadan önceki bir satırda çağırabilirsin:
Bu kod sorunsuz çalışır. Motor, çalıştırmaya başlamadan önce scope'u tarar, square'ı bir fonksiyon olarak kaydeder ve ardından ifadeleri yukarıdan aşağıya sırayla işletmeye başlar.
Bu, function declaration ile fonksiyon oluşturmanın diğer yolları (function expression, arrow function) arasındaki gerçek bir davranış farkıdır. Diğerleri değişkenler gibi hoist edilir — yani isim bilinir ama değer, ilgili satır çalışana kadar atanmaz. Bu ayrıma birazdan daha detaylı değineceğiz.
Zaten çoğu stil rehberi, fonksiyonları çağırmadan önce tanımlamanızı öneriyor. Hoisting bir güvenlik ağıdır; üzerine inşa edilecek bir stil değil.
Function Declaration ve Function Expression Farkı
Function declaration, tek başına bir statement olarak durur. Function expression ise bir değer beklenen yerde kullanılır — en sık olarak bir atamanın sağ tarafında:
Her ikisi de çağrılabilir fonksiyon üretir. Aradaki farklar şöyle:
- Declaration'lar tamamen hoist edilir. Expression'lar ise atandıkları değişkenin hoisting kurallarına uyar (
constvelet, ilgili satır çalışana kadar temporal dead zone'da kalır). - Declaration'ların mutlaka bir ismi olmak zorundadır. Expression'lar ise isimsiz olabilir; yine de isim vermek stack trace'lerde işinizi kolaylaştırır.
- Declaration'ları istediğiniz her yere koyamazsınız. Strict mode'da bir
ifbloğunun içindekifunction foo() {}motordan motora farklı davranır — orada expression kullanmak daha güvenlidir.
Bir dosyanın en üst seviyesindeki yardımcı fonksiyonlar için declaration gayet okunaklı durur. Argüman olarak geçilen ya da bir özelliğe atanan fonksiyonlar içinse genelde expression (veya arrow function) tercih edilir.
İsimlendirme ve Stil
Fonksiyonun adı, o fonksiyonun ne yaptığına dair verdiğiniz bir sözdür. Açıklayıcı bir isim seçmek için harcadığınız birkaç fazladan karakter, kodu okuyan ilk kişiyle birlikte kendini fazlasıyla amorti eder.
Benimsemeye değer birkaç kural var:
- Fonksiyon isimleri fiil olmalı:
fetchProfile,computeTotal,sendEmail. camelCasekullanın — JavaScript'te standart budur.- Boolean döndüren fonksiyonlar genellikle
is,hasya dacanile başlar:isValid,hasAccess,canEdit.
Amaç, fonksiyonu çağırdığınız satırın neredeyse bir cümle gibi okunması.
Küçük Bir Çalışan Örnek
Şimdi parçaları bir araya getirelim — parametreler, erken return ve anlamlı bir isim:
Tek bir declaration, bir guard clause ve net bir return. Yazacağın fonksiyonların büyük çoğunluğu aslında bu kalıba uyar.
Sırada: Arrow Function'lar
Function declaration'lar işin bel kemiği, ama modern JavaScript daha kısa bir sözdizimine — yani arrow function'lara — ciddi şekilde yaslanıyor; özellikle callback'lerde ve tek satırlık fonksiyonlarda. Görünüşleri farklı, this davranışları farklı ve bir sonraki sayfanın konusu tam olarak bunlar.
Sıkça Sorulan Sorular
JavaScript'te bir fonksiyon nasıl tanımlanır?
function anahtar kelimesini yazıp ardından bir isim, parametreler için parantez ve süslü parantezli bir blok eklersin. Örneğin: function greet(name) { return 'Merhaba, ' + name; }. Çağırmak için de ismini parantezlerle birlikte kullanırsın: greet('Ada').
JavaScript'te function hoisting nedir?
Function declaration'lar, kod çalışmadan önce bulundukları scope'un en üstüne taşınır. Yani fonksiyonu, tanımlandığı satırdan önceki bir satırda bile çağırabilirsin. Ama bu sadece function declaration'lar için geçerli — let veya const ile atanan function expression'lar ve arrow function'lar bu şekilde hoist edilmez.
Function declaration ile function expression arasındaki fark nedir?
Declaration tek başına bir ifadedir (function greet() {}) ve hoist edilir. Expression ise fonksiyonu bir değişkene atar (const greet = function() {}) ve sıradan değişken hoisting kurallarına tabidir. Declaration'ın tanımı gereği bir ismi vardır; expression'lar ise çoğu zaman anonimdir.