Tüm blog yazıları

Constructor Functions ve new Keyword

Factory Function'ların hafıza israfı sorununa Constructor Function'lar ve new keyword'ü ile son verin! Metotları paylaştırarak JavaScript objelerini daha verimli nasıl oluşturacağınızı, new'in perde arkasında neler yaptığını ve prototype sisteminin gücünü bu rehberde keşfedin.

eminbasbayan8 dk okuma
JavaScript kodunda Constructor Function ve new keyword'ü ile nesne oluşturma örnekleri

Önceki makalede Factory Function'ların bir sorununu gördük: her nesne oluşturulduğunda metotların yeni kopyaları üretiliyor. Bu hafıza israfına yol açıyordu.

Peki metotları nasıl paylaştırabiliriz? İşte Constructor Functions ve new keyword'ü tam da bu sorunu çözmek için var. Prototype sistemini kullanarak metotları tek bir yerde tutmamızı sağlar.

new Keyword'ü Zaten Kullanıyorsunuz!

Aslında new keyword'ünü daha önce görmüştük:

javascript
// Array oluşturma (alternatif yol)
const dizi = new Array(1, 2, 3);

// Date nesnesi
const tarih = new Date();

// XMLHttpRequest
const xhr = new XMLHttpRequest();

// RegExp
const regex = new RegExp("\\d+");

Tüm bu new ile başlayan ifadeler bir constructor function çağırıyor!

Constructor Function Nedir?

Constructor Function, new keyword'ü ile çağrıldığında yeni nesne oluşturan özel bir fonksiyondur.

Temel Yapı

javascript
// Constructor function - büyük harfle başlar (convention)
function Kullanici(ad, yas) {
    this.ad = ad;
    this.yas = yas;
}

// new ile çağırma
const kullanici1 = new Kullanici("Ahmet", 25);
const kullanici2 = new Kullanici("Ayşe", 30);

console.log(kullanici1);  // Kullanici {ad: "Ahmet", yas: 25}
console.log(kullanici2);  // Kullanici {ad: "Ayşe", yas: 30}

Dikkat Edilecekler

  1. İsim büyük harfle başlar - Kullanici, Araba, Urun (convention)
  2. return yok - new otomatik olarak nesneyi döndürür
  3. this kullanılır - Oluşturulan nesneye özellik eklemek için

new Keyword Ne Yapar?

new keyword'ü 4 önemli işlem yapar:

javascript
function Araba(marka, model) {
    // new çağrıldığında arka planda:

    // 1. Boş bir nesne oluşturulur
    // this = {}

    // 2. this.__proto__ = Araba.prototype olarak ayarlanır

    // 3. Fonksiyon çalışır, this'e özellikler eklenir
    this.marka = marka;
    this.model = model;

    // 4. this otomatik olarak döndürülür
    // return this
}

Görsel Temsil

metin
new Araba("Toyota", "Corolla") çağrıldığında:

┌─────────────────────────────────────────────────────┐
│  1. Boş nesne oluştur:     this = {}                │
│  2. Prototype bağla:       this.__proto__ = Araba.prototype │
│  3. Fonksiyonu çalıştır:   this.marka = "Toyota"    │
│                            this.model = "Corolla"   │
│  4. Nesneyi döndür:        return this              │
└─────────────────────────────────────────────────────┘
                            │
                            ▼
              { marka: "Toyota", model: "Corolla" }

new Olmadan Çağırırsak?

javascript
function Kullanici(ad) {
    this.ad = ad;
    console.log(this);
}

// new ile - DOĞRU
const user1 = new Kullanici("Ali");
// this = yeni oluşturulan nesne
// Çıktı: Kullanici {ad: "Ali"}

// new olmadan - YANLIŞ!
const user2 = Kullanici("Veli");
// this = window (global object)
// user2 = undefined (return yok!)
// window.ad = "Veli" oldu! 😱

Önemli: Constructor function'ları her zaman new ile çağırın!

Prototype'a Metot Ekleme

İşte constructor function'ların asıl gücü! Metotları prototype'a ekleyerek tüm nesneler arasında paylaştırabilirsiniz:

javascript
// Constructor function
function Hesap(sahibi, bakiye) {
    this.sahibi = sahibi;
    this.bakiye = bakiye;
}

// Metotları prototype'a ekle
Hesap.prototype.paraYatir = function(miktar) {
    this.bakiye += miktar;
    console.log(`${miktar} TL yatırıldı. Bakiye: ${this.bakiye} TL`);
};

Hesap.prototype.paraCek = function(miktar) {
    if (miktar > this.bakiye) {
        console.log("Yetersiz bakiye!");
        return;
    }
    this.bakiye -= miktar;
    console.log(`${miktar} TL çekildi. Bakiye: ${this.bakiye} TL`);
};

Hesap.prototype.bilgiGoster = function() {
    console.log(`${this.sahibi} - ${this.bakiye} TL`);
};

Kullanım

javascript
const hesap1 = new Hesap("Mehmet", 1000);
const hesap2 = new Hesap("Zeynep", 5000);

hesap1.paraYatir(500);   // 500 TL yatırıldı. Bakiye: 1500 TL
hesap2.paraCek(1000);    // 1000 TL çekildi. Bakiye: 4000 TL

hesap1.bilgiGoster();    // Mehmet - 1500 TL
hesap2.bilgiGoster();    // Zeynep - 4000 TL

Factory vs Constructor: Hafıza Karşılaştırması

javascript
// Metotların aynı olup olmadığını kontrol edelim

// FACTORY FUNCTION
function fabrikaKullanici(ad) {
    return {
        ad,
        selamla() { console.log(`Merhaba, ${this.ad}`); }
    };
}

const fUser1 = fabrikaKullanici("Ali");
const fUser2 = fabrikaKullanici("Veli");

console.log(fUser1.selamla === fUser2.selamla);  // false ❌
// Her nesnenin AYRI metot kopyası var!


// CONSTRUCTOR FUNCTION
function ConstKullanici(ad) {
    this.ad = ad;
}

ConstKullanici.prototype.selamla = function() {
    console.log(`Merhaba, ${this.ad}`);
};

const cUser1 = new ConstKullanici("Ali");
const cUser2 = new ConstKullanici("Veli");

console.log(cUser1.selamla === cUser2.selamla);  // true ✅
// İkisi de AYNI metodu paylaşıyor!

Görsel Karşılaştırma

metin
FACTORY FUNCTION:
┌──────────┐  ┌──────────┐
│  fUser1  │  │  fUser2  │
│ ad:"Ali" │  │ ad:"Veli"│
│ selamla()│  │ selamla()│  ← Her birinin AYRI kopyası
└──────────┘  └──────────┘


CONSTRUCTOR FUNCTION:
┌──────────┐  ┌──────────┐
│  cUser1  │  │  cUser2  │
│ ad:"Ali" │  │ ad:"Veli"│
│__proto__─┼──┼─__proto__│
└──────────┘  └──────────┘
      │            │
      └─────┬──────┘
            ▼
   ┌─────────────────┐
   │   Prototype     │
   │  selamla()      │  ← TEK kopya, paylaşılıyor
   └─────────────────┘

Pratik Örnek: Oyuncu Sistemi

javascript
// Constructor function
function Oyuncu(isim, seviye) {
    this.isim = isim;
    this.seviye = seviye || 1;
    this.deneyim = 0;
    this.can = 100;
}

// Prototype metotları
Oyuncu.prototype.deneyimKazan = function(miktar) {
    this.deneyim += miktar;
    console.log(`${this.isim} ${miktar} XP kazandı!`);

    // Seviye atlama kontrolü
    if (this.deneyim >= this.seviye * 100) {
        this.seviyeAtla();
    }
};

Oyuncu.prototype.seviyeAtla = function() {
    this.seviye++;
    this.deneyim = 0;
    this.can = 100;  // Can yenilenir
    console.log(`🎉 ${this.isim} seviye atladı! Yeni seviye: ${this.seviye}`);
};

Oyuncu.prototype.hasarAl = function(miktar) {
    this.can -= miktar;
    console.log(`${this.isim} ${miktar} hasar aldı. Can: ${this.can}`);

    if (this.can <= 0) {
        console.log(`💀 ${this.isim} öldü!`);
    }
};

Oyuncu.prototype.durum = function() {
    console.log(`
    ══════════════════════
    İsim: ${this.isim}
    Seviye: ${this.seviye}
    XP: ${this.deneyim}/${this.seviye * 100}
    Can: ${this.can}/100
    ══════════════════════
    `);
};

Kullanım

javascript
const oyuncu1 = new Oyuncu("DragonSlayer", 1);
const oyuncu2 = new Oyuncu("ShadowNinja", 3);

oyuncu1.deneyimKazan(50);   // DragonSlayer 50 XP kazandı!
oyuncu1.deneyimKazan(60);   // DragonSlayer 60 XP kazandı!
                             // 🎉 DragonSlayer seviye atladı! Yeni seviye: 2

oyuncu1.hasarAl(30);        // DragonSlayer 30 hasar aldı. Can: 70
oyuncu1.durum();

// Metotların paylaşıldığını doğrula
console.log(oyuncu1.durum === oyuncu2.durum);  // true

Pratik Örnek: Ürün Kataloğu

javascript
function Urun(ad, fiyat, kategori) {
    this.ad = ad;
    this.fiyat = fiyat;
    this.kategori = kategori;
    this.stok = 0;
    this.indirimOrani = 0;
}

Urun.prototype.stokEkle = function(adet) {
    this.stok += adet;
    return this;  // Zincirleme için
};

Urun.prototype.stokCikar = function(adet) {
    if (adet > this.stok) {
        console.log(`Yetersiz stok! Mevcut: ${this.stok}`);
        return this;
    }
    this.stok -= adet;
    return this;
};

Urun.prototype.indirimYap = function(yuzde) {
    this.indirimOrani = yuzde;
    return this;
};

Urun.prototype.guncelFiyat = function() {
    const indirim = this.fiyat * (this.indirimOrani / 100);
    return this.fiyat - indirim;
};

Urun.prototype.ozet = function() {
    const fiyatStr = this.indirimOrani > 0
        ? `${this.fiyat} TL → ${this.guncelFiyat()} TL (%${this.indirimOrani} indirim)`
        : `${this.fiyat} TL`;

    console.log(`[${this.kategori}] ${this.ad} - ${fiyatStr} (Stok: ${this.stok})`);
};

Kullanım

javascript
const laptop = new Urun("MacBook Pro", 75000, "Elektronik");
const telefon = new Urun("iPhone 15", 55000, "Elektronik");

// Zincirleme kullanım
laptop.stokEkle(10).indirimYap(15);
telefon.stokEkle(25);

laptop.ozet();
// [Elektronik] MacBook Pro - 75000 TL → 63750 TL (%15 indirim) (Stok: 10)

telefon.ozet();
// [Elektronik] iPhone 15 - 55000 TL (Stok: 25)

Arrow Function Kullanmayın!

Constructor prototype'larında arrow function kullanmayın. Arrow function'lar this'i farklı işler:

javascript
function Kisi(ad) {
    this.ad = ad;
}

// ❌ YANLIŞ - Arrow function
Kisi.prototype.selamlaYanlis = () => {
    console.log(`Merhaba, ${this.ad}`);  // this = window!
};

// ✅ DOĞRU - Normal function
Kisi.prototype.selamlaDogru = function() {
    console.log(`Merhaba, ${this.ad}`);  // this = nesne
};

const kisi = new Kisi("Ali");
kisi.selamlaYanlis();  // Merhaba, undefined
kisi.selamlaDogru();   // Merhaba, Ali

instanceof Operatörü

Bir nesnenin hangi constructor'dan oluşturulduğunu kontrol edebilirsiniz:

javascript
function Araba(marka) {
    this.marka = marka;
}

function Bisiklet(marka) {
    this.marka = marka;
}

const toyota = new Araba("Toyota");
const bianchi = new Bisiklet("Bianchi");

console.log(toyota instanceof Araba);     // true
console.log(toyota instanceof Bisiklet);  // false
console.log(bianchi instanceof Bisiklet); // true

// Tüm nesneler Object'ten türer
console.log(toyota instanceof Object);    // true

Constructor Function'ın Dezavantajları

1. Dağınık Sözdizimi

javascript
// Constructor ayrı
function Hayvan(isim) {
    this.isim = isim;
}

// Metotlar ayrı ayrı
Hayvan.prototype.konus = function() { ... };
Hayvan.prototype.yuru = function() { ... };
Hayvan.prototype.ye = function() { ... };

// Kod dağınık ve takibi zor

2. new Unutma Riski

javascript
const kedi = Hayvan("Tekir");  // new unutuldu!
// kedi = undefined
// window.isim = "Tekir" 😱

3. Okunabilirlik

javascript
// Birçok prototype tanımı ardarda...
Urun.prototype.metot1 = function() { ... };
Urun.prototype.metot2 = function() { ... };
Urun.prototype.metot3 = function() { ... };
// Hangi metot nereye ait? Karışık!

Özet

javascript
// Constructor Function şablonu
function NesneAdi(param1, param2) {
    this.ozellik1 = param1;
    this.ozellik2 = param2;
}

// Metotları prototype'a ekle
NesneAdi.prototype.metot1 = function() {
    // this.ozellik1 kullan
};

NesneAdi.prototype.metot2 = function() {
    // this.ozellik2 kullan
};

// Kullanım - new ile!
const nesne = new NesneAdi(deger1, deger2);
ÖzellikFactory FunctionConstructor Function
Çağırmafonksiyon()new Fonksiyon()
Metot paylaşımı❌ Her nesne kendi kopyasını taşır✅ Prototype'ta paylaşılır
HafızaDaha fazla kullanırDaha verimli
instanceof❌ Çalışmaz✅ Çalışır
SyntaxBasitDağınık

Sırada Ne Var?

Constructor function'lar çalışıyor ama syntax'ı dağınık: constructor ayrı, prototype metotları ayrı...

ES6 ile gelen class syntax'ı tüm bunları tek bir yapı altında toplar. Aynı işi yapar ama çok daha temiz ve okunabilir kod yazmanızı sağlar.

Bir sonraki makalede JavaScript Classes konusunu öğreneceğiz - modern ve önerilen yöntem!

JavaScript Classes ile pratik uygulamalar, metotlar arası iletişim ve gerçek dünya kod örnekleri
JavaScript Dersleri9 dk okuma

JavaScript Classes - Pratik Uygulamalar

JavaScript class'ları ile pratik uygulamalara geçin! Metotlar arası iletişimden constructor'da metot çağırmaya, kod tekrarını azaltmaktan gerçek dünya senaryolarına kadar class kullanımının inceliklerini keşfedin. Kendi alışveriş sepeti örneğinizle bilginizi pekiştirin.

Yazıyı oku
JavaScript class yapısını gösteren bir kod örneği, ES6 ile modern nesne oluşturma
JavaScript Dersleri9 dk okuma

JavaScript Classes

ES6 ile JavaScript'e gelen class yapısı sayesinde nesne oluşturmak artık çok daha kolay ve düzenli! Constructor function karmaşasından kurtulup, okunabilir ve yönetilebilir kodlar yazmak isteyenler için modern JavaScript'in temel taşı olan class'ları tüm detaylarıyla keşfedin. Bu rehberle nesne şabl

Yazıyı oku
JavaScript Factory Functions kavramını gösteren bir fabrika bandı görseli. Kodlama ile nesne oluşturma sürecini temsil ediyor.
JavaScript Dersleri6 dk okuma

Factory Functions Nedir?

JavaScript'te nesne oluşturmanın en basit ve etkili yolu olan Factory Functions'ı keşfedin! Bu rehberde, nesne tabanlı programlamanın temelini oluşturan bu 'fabrika fonksiyonları' ile nasıl esnek ve yeniden kullanılabilir nesneler üreteceğinizi adım adım öğrenin.

Yazıyı oku

Çerez tercihlerin

Platformun çalışması için zorunlu çerezler kullanıyoruz. İzin verirsen anonim kullanım verilerini ölçüyoruz. Ayrıntıları incele