JavaScript’te “Constructor Functions” (Yapıcı Fonksiyonlar)
Bu yazımızda, JavaScript’te prototip tabanlı kalıtımın temel taşlarından biri olan ve “constructor functions” olarak adlandırılan “yapıcı fonksiyonlar” kavramını ele alacağız.
JavaScript’te “Constructor Functions” Kullanımı
JavaScript, nesnelerin diğer nesnelerden miras alabilmesini sağlayan prototip tabanlı bir programlama dilidir. İşte bu miras mekanizmasının temeli yapıcı fonksiyonlar ile sağlanır.
O halde, JavaScript’te yapıcı fonksiyonların nasıl oluşturulduğunu inceleyelim. JavaScript’te yapıcı fonksiyonlar, ilk harfi büyük olacak şekilde bir “PascalCase” ile isimlendirilir ve “new” anahtar kelimesiyle birlikte kullanıldığında yeni bir nesne oluşturmak için tasarlanmıştır.
Fonksiyonun gövdesinde yazılan “this” anahtar kelimesi, oluşturulan yeni nesneyi temsil eder. Böylece, belirli özellikler ve metotlar bu yeni nesneye atanabilir.
Yani, yapıcı fonksiyonlar “new” anahtar kelimesi ile çağrıldığında, o an oluşturulan nesneyi “this” anahtar kelimesiyle temsil ederler. Bu “this” içerisinde tanımlanan özellikler ve metotlar ise yeni nesneye atanır. Fonksiyonun sonunda, eğer özellikle başka bir şey döndürülmezse, bu “this” ile temsil edilen nesne otomatik olarak döndürülür. Örneğin:
1 2 3 4 5 6 7 8 9 10 11 |
function Kisi(ad, soyad) { this.ad = ad; this.soyad = soyad; this.tamAd = function() { return this.ad + " " + this.soyad; } } const kisi1 = new Kisi("John", "Doe"); console.log(kisi1.tamAd()); // John Doe |
Yukarıdaki örneğimizde, new
anahtar kelimesiyle birlikte Kisi
fonksiyonunu çağırarak yeni bir nesne oluşturduk. Yapıcı fonksiyon içindeki this
anahtar kelimesi ise, o an oluşturulan nesneyi, yani kisi1
‘i, temsil etmektedir.
Yapıcı fonksiyonların en büyük avantajlarından biri, prototipleme yoluyla metotları ve özellikleri paylaşmalarıdır. Özellikle, birçok nesnenin ortak bir fonksiyonu veya özelliği kullanması gerektiğinde bu yapı tercih edilir. Söz dizimi (syntax) ise aşağıdaki gibidir:
1 2 3 |
ConstructorFunctionName.prototype.methodName = function() { // metodun içeriği }; |
Bellekte aynı fonksiyon için sadece bir kopya bulunmasından ötürü performans açısından da avantajlıdır. Örneğimizi bu şekilde genişletelim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function Kisi(ad, soyad) { this.ad = ad; this.soyad = soyad; } // Şimdi Kisi'nin prototipine bir metod ekleyelim. Kisi.prototype.tamAd = function() { return this.ad + " " + this.soyad; } // Yeni bir Kisi nesnesi oluşturalım. var john = new Kisi("John", "Doe"); // tamAd metodunu kullanalım. console.log(john.tamAd()); // "John Doe" olarak çıktı alınır. |
Bu yapı sayesinde, Kisi
yapıcı fonksiyonuyla oluşturduğumuz tüm nesneler, tamAd
metodu üzerinden tam adını alabilirler. Ancak önemli olan şu ki, tamAd
metodu bellekte sadece bir kere saklanır. Yani, 1000 tane Kisi
nesnesi olsun, hepsi bu tek tamAd
metoduna erişebilir ama bellekte sadece bir kopyası bulunur. Bu, özellikle büyük uygulamalar için performansı olumlu etkileyen bir durumdur.
Yapıcı Fonksiyonların Normal Fonksiyonlardan Farkı
JavaScript’te normal fonksiyonlarla yapıcı fonksiyonlar arasında birtakım farklılıklar bulunmaktadır. Bunlar genel hatlarıyla aşağıdaki gibidir:
- Fonksiyon adlandırması: Yapıcı fonksiyonlar genellikle büyük harfle başlar. Bu, onları normal fonksiyonlardan ayırmak için kullanılan yazısız bir kuraldır. Örneğimizde kullandığımız
Kisi
fonksiyonu, adlandırması sayesinde yapıcı bir fonksiyon olduğu belli olmaktadır. - “this” anahtar kelimesi: Yapıcı fonksiyonlar genellikle
this
anahtar kelimesini kullanır.this
, yeni oluşturulan objeyi gösterir vethis
kullanarak bu objeye özellikler ve metotlar ekleyebiliriz. - Yapıcı fonksiyonlarda return kullanımı: Normal fonksiyonlar, eğer bir
return
ifadesi tanımlanmışsa belirli bir değer döndürebilir ya da hiçbir şey döndürmeyebilir. Yapıcı fonksiyonlarda, eğer özellikle bir şey döndürülmezse,this
ile temsil edilen nesne otomatik olarak döndürülür. - Prototype özelliği: Yapıcı fonksiyonlar, oluşturulan nesnelere prototip mirası sağlar. Bu işlem,
YapiciFonksiyonAdi.prototype
üzerinden gerçekleştirilir. Normal fonksiyonlar için bu tür bir prototip mirası söz konusu değildir.
Bu farklılıkların yanı sıra, aslında her iki fonksiyon türü de JavaScript’te fonksiyon olarak tanımlanmaktadır. Fakat kullanım amacı ve yukarıda belirttiğimiz farklılıklar, onları birbirinden ayırır.