- Konu sahibi
- #1
JavaScript’te constructor, yeni nesneyi oluşturma ve başlangıç değerlerini hazırlama rolünü anlatır. Bir class içindeki
Bu kodda
Beklenen çıktı şöyledir:
İlk satırda isim doğru görünüyorsa constructor parametresinin nesne özelliğine aktarıldığını anlarsınız.
Temel bir sınıftan
Sınıf ve constructor ilişkisini şu şekilde düşünebilirsiniz:
Bir sınıf başka bir sınıfı
Burada
Yapıcı olarak kullanılan normal fonksiyonlar da vardır ve hâlâ kullanılabilir. Aşağıdaki örneği önceki User tanımından ayrı çalıştırın; aynı kapsamda iki User tanımı yazmayın:
Burada fonksiyon
Constructor parametresi ile nesne özelliği aynı ada sahip olabilir. Bu durumda
Constructor içinde yapılacak başlangıç işlemi yoksa boş bir constructor eklemek yerine sınıfı doğrudan tanımlamak daha temizdir. Miras alınan sınıfta ise kendi başlangıç işlemleriniz varsa
Class constructor metodu async olamaz. Asenkron veri hazırlanması gerekiyorsa nesneyi bir async fabrika fonksiyonunda oluşturmak veya açıkça çağrılan ayrı bir başlatma metodu tasarlamak mümkündür. Yeni nesneyi kullanan kod hazırlığın tamamlanmasını ayrıca beklemelidir.
Hayır. Bir class içinde yalnızca bir
Normal başlangıç kodunda açık return yazmanız gerekmez. Temel sınıfın constructor’ı bir nesne döndürürse bu nesne oluşturulan örneğin yerini alabilir; ilkel değer dönüşü ise yok sayılır. Miras alan sınıfın constructor’ında nesne olmayan, undefined dışındaki bir değer döndürmek TypeError üretir. Bu nedenle “her return aynı şekilde davranır” varsayımıyla tasarım yapmayın.
constructor bu iş için özel metottur; new ile çağrılan uygun fonksiyonlar da yapıcı olarak kullanılabilir. En yaygın kullanım şekli, bir class içinde tanımlanması ve new operatörüyle yeni nesne üretilmesidir. Örneğin kullanıcı adı ve e-posta gibi bilgileri her nesne için başlangıçta ayarlamak istiyorsanız bunu constructor içinde yaparsınız.Temel kullanım
Kod:
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
describe() {
return `${this.name} - ${this.email}`;
}
}
const user = new User("Ayşe", "[email protected]");
console.log(user.name);
console.log(user.describe());
Bu kodda
new User(...) çalıştırıldığında yeni bir User nesnesi oluşturulur. Constructor içindeki this, oluşturulan bu yeni nesneyi gösterir. this.name ve this.email atamaları, nesnenin başlangıç özelliklerini oluşturur.Beklenen çıktı şöyledir:
Kod:
Ayşe
Ayşe - [email protected]
İlk satırda isim doğru görünüyorsa constructor parametresinin nesne özelliğine aktarıldığını anlarsınız.
undefined görürseniz genellikle nesneyi oluştururken parametre vermemiş veya özellik adını yanlış yazmışsınızdır.Constructor nasıl çalışır?
Temel bir sınıftan
new ile nesne üretme işlemi, aşağıdaki gibi basitleştirilebilir. Miras alan sınıfta this bağlantısının kurulması ayrıca super çağrısına bağlıdır:- Yeni bir nesne oluşturur.
- Bu nesneyi sınıfın prototype zincirine bağlar.
- Constructor parametrelerini alır.
- Constructor içindeki başlangıç atamalarını çalıştırır.
- Hazırlanan nesneyi sonuç olarak döndürür.
Sınıf ve constructor ilişkisini şu şekilde düşünebilirsiniz:
| Kavram | Görevi | Örnek |
|---|---|---|
| class | Nesnelerin yapısını ve davranışlarını tanımlar | class User |
| constructor | Yeni nesnenin ilk değerlerini hazırlar | constructor(name) |
| new | Sınıftan yeni nesne üretir | new User("Ayşe") |
Miras alınan sınıflarda super kullanımı
Bir sınıf başka bir sınıfı
extends ile miras alıyorsa, alt sınıfın constructor'ında this kullanılmadan önce super() çağrılmalıdır.
Kod:
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}
const dog = new Dog("Karabaş", "Kangal");
console.log(dog.name); // Karabaş
console.log(dog.breed); // Kangal
Burada
super(name), üst sınıf olan Animal constructor'ını çalıştırır. super() çağrılmadan this.breed yazılırsa ReferenceError oluşur. Çünkü alt sınıfın nesnesi henüz başlatılmamıştır.Fonksiyon constructor ile farkı
Yapıcı olarak kullanılan normal fonksiyonlar da vardır ve hâlâ kullanılabilir. Aşağıdaki örneği önceki User tanımından ayrı çalıştırın; aynı kapsamda iki User tanımı yazmayın:
Kod:
function User(name) {
this.name = name;
}
const user = new User("Mehmet");
console.log(user.name); // Mehmet
Burada fonksiyon
new ile çağrıldığı için constructor gibi davranır. Ancak class constructor'ları doğrudan çağrılamaz; User() yerine new User() kullanılmalıdır. Constructor amacınız nesne oluşturmaksa sınıf adını büyük harfle başlatmak, gerekli parametreleri açıkça tanımlamak ve başlangıç atamalarını constructor içinde toplamak okunabilirliği artırır.Sık yapılan hatalar
new kullanmamak
const user = User("Ayşe") biçimi class için hatalıdır ve "class constructors must be invoked with 'new'" türünde hata üretir. Doğru kullanım const user = new User("Ayşe") şeklindedir.this yerine yanlış değişken kullanmak
Constructor parametresi ile nesne özelliği aynı ada sahip olabilir. Bu durumda
this.name = name yazılmalıdır. Sadece name = name yazmak nesneye özellik eklemez.Gereksiz constructor yazmak
Constructor içinde yapılacak başlangıç işlemi yoksa boş bir constructor eklemek yerine sınıfı doğrudan tanımlamak daha temizdir. Miras alınan sınıfta ise kendi başlangıç işlemleriniz varsa
super() çağrısını ve ardından alt sınıfa ait atamaları yapın.Sık sorulan sorular
Constructor async olabilir mi?
Class constructor metodu async olamaz. Asenkron veri hazırlanması gerekiyorsa nesneyi bir async fabrika fonksiyonunda oluşturmak veya açıkça çağrılan ayrı bir başlatma metodu tasarlamak mümkündür. Yeni nesneyi kullanan kod hazırlığın tamamlanmasını ayrıca beklemelidir.
Bir class içinde birden fazla constructor olabilir mi?
Hayır. Bir class içinde yalnızca bir
constructor metodu bulunabilir. Farklı parametre senaryoları için varsayılan değerler veya koşullu mantık kullanılabilir.Constructor içinde return kullanırsam ne olur?
Normal başlangıç kodunda açık return yazmanız gerekmez. Temel sınıfın constructor’ı bir nesne döndürürse bu nesne oluşturulan örneğin yerini alabilir; ilkel değer dönüşü ise yok sayılır. Miras alan sınıfın constructor’ında nesne olmayan, undefined dışındaki bir değer döndürmek TypeError üretir. Bu nedenle “her return aynı şekilde davranır” varsayımıyla tasarım yapmayın.