Tüm blog yazıları

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

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

JavaScript Classes

Giriş

Önceki makalede constructor function'ları gördük. Çalışıyorlar ama syntax'ları dağınık: constructor bir yerde, prototype metotları başka yerde...

ES6 (2015) ile JavaScript'e class syntax'ı geldi. Aynı işi yapıyor ama çok daha temiz, organize ve okunabilir kod yazmanızı sağlıyor. Modern JavaScript'te nesne şablonları oluşturmanın önerilen yöntemi budur.

Class Nedir?

Class, nesne oluşturmak için kullanılan bir şablondur. Aslında constructor function'ların üzerine giydirilmiş "syntactic sugar" (sözdizimsel şeker) - yani aynı işi yapan daha güzel bir yazım şekli.

En Basit Class

javascript
class Kullanici {
    constructor(ad, yas) {
        this.ad = ad;
        this.yas = yas;
    }
}

const kullanici1 = new Kullanici("Ahmet", 25);
console.log(kullanici1);  // Kullanici {ad: "Ahmet", yas: 25}

Class Yapısı

javascript
class SinifAdi {
    // Constructor: Nesne oluşturulurken çalışır
    constructor(param1, param2) {
        this.ozellik1 = param1;
        this.ozellik2 = param2;
    }

    // Metotlar: Otomatik olarak prototype'a eklenir
    metot1() {
        // ...
    }

    metot2() {
        // ...
    }
}

Temel Kurallar

  1. class keyword'ü ile başlar
  2. İsim büyük harfle başlar (convention): Kullanici, Araba, Urun
  3. constructor metodu zorunludur (nesne oluşturulurken çalışır)
  4. Metotlar arasında virgül yok
  5. new keyword'ü ile çağrılır

Constructor Metodu

constructor, class'tan yeni bir nesne oluşturulduğunda otomatik olarak çalışan özel metottur.

javascript
class Ogrenci {
    constructor(ad, numara) {
        console.log("Constructor çalıştı!");

        // this = yeni oluşturulan nesne
        this.ad = ad;
        this.numara = numara;
        this.notlar = [];
    }
}

const ogrenci1 = new Ogrenci("Ali", 1234);
// Konsol: "Constructor çalıştı!"
// ogrenci1 = {ad: "Ali", numara: 1234, notlar: []}

Constructor'da Yapılanlar

javascript
class Urun {
    constructor(ad, fiyat) {
        // 1. Özellikleri ayarla
        this.ad = ad;
        this.fiyat = fiyat;

        // 2. Varsayılan değerler ata
        this.stok = 0;
        this.aktif = true;

        // 3. Hesaplamalar yap
        this.kdvliFiyat = fiyat * 1.20;

        // 4. Doğrulama yap
        if (fiyat < 0) {
            throw new Error("Fiyat negatif olamaz!");
        }
    }
}

Metot Tanımlama

Class içinde tanımlanan metotlar otomatik olarak prototype'a eklenir. Bu sayede tüm nesneler aynı metotları paylaşır.

javascript
class Hesap {
    constructor(sahibi, bakiye) {
        this.sahibi = sahibi;
        this.bakiye = bakiye;
    }

    // Metotlar - prototype'a eklenir
    paraYatir(miktar) {
        this.bakiye += miktar;
        console.log(`${miktar} TL yatırıldı.`);
    }

    paraCek(miktar) {
        if (miktar > this.bakiye) {
            console.log("Yetersiz bakiye!");
            return false;
        }
        this.bakiye -= miktar;
        console.log(`${miktar} TL çekildi.`);
        return true;
    }

    bakiyeGoster() {
        console.log(`${this.sahibi}: ${this.bakiye} TL`);
    }
}

Kullanım

javascript
const hesap1 = new Hesap("Mehmet", 1000);
const hesap2 = new Hesap("Ayşe", 5000);

hesap1.paraYatir(500);    // 500 TL yatırıldı.
hesap1.bakiyeGoster();    // Mehmet: 1500 TL

hesap2.paraCek(2000);     // 2000 TL çekildi.
hesap2.bakiyeGoster();    // Ayşe: 3000 TL

// Metotlar paylaşılıyor mu?
console.log(hesap1.paraYatir === hesap2.paraYatir);  // true ✅

Constructor Function vs Class Karşılaştırması

Eski Yöntem: Constructor Function

javascript
// Constructor
function Araba(marka, model) {
    this.marka = marka;
    this.model = model;
}

// Metotlar ayrı ayrı tanımlanır
Araba.prototype.bilgiVer = function() {
    return `${this.marka} ${this.model}`;
};

Araba.prototype.calistir = function() {
    console.log("Motor çalıştı!");
};

Araba.prototype.durdur = function() {
    console.log("Motor durdu!");
};

Yeni Yöntem: Class

javascript
class Araba {
    constructor(marka, model) {
        this.marka = marka;
        this.model = model;
    }

    // Tüm metotlar bir arada!
    bilgiVer() {
        return `${this.marka} ${this.model}`;
    }

    calistir() {
        console.log("Motor çalıştı!");
    }

    durdur() {
        console.log("Motor durdu!");
    }
}

Fark: Class ile her şey tek bir blok içinde, organize ve okunabilir!

Pratik Örnek: Todo Uygulaması

javascript
class TodoListesi {
    constructor(baslik) {
        this.baslik = baslik;
        this.gorevler = [];
    }

    gorevEkle(metin) {
        const gorev = {
            id: Date.now(),
            metin: metin,
            tamamlandi: false,
            tarih: new Date().toLocaleDateString("tr-TR")
        };
        this.gorevler.push(gorev);
        console.log(`✅ Görev eklendi: "${metin}"`);
        return gorev;
    }

    gorevTamamla(id) {
        const gorev = this.gorevler.find(g => g.id === id);
        if (gorev) {
            gorev.tamamlandi = true;
            console.log(`✓ Tamamlandı: "${gorev.metin}"`);
        }
    }

    gorevSil(id) {
        const index = this.gorevler.findIndex(g => g.id === id);
        if (index > -1) {
            const silinen = this.gorevler.splice(index, 1)[0];
            console.log(`🗑️ Silindi: "${silinen.metin}"`);
        }
    }

    bekleyenler() {
        return this.gorevler.filter(g => !g.tamamlandi);
    }

    tamamlananlar() {
        return this.gorevler.filter(g => g.tamamlandi);
    }

    ozet() {
        const bekleyen = this.bekleyenler().length;
        const tamamlanan = this.tamamlananlar().length;
        console.log(`
📋 ${this.baslik}
────────────────────
Toplam: ${this.gorevler.length} görev
Bekleyen: ${bekleyen}
Tamamlanan: ${tamamlanan}
────────────────────`);
    }

    listele() {
        console.log(`\n📋 ${this.baslik}\n`);
        this.gorevler.forEach(g => {
            const durum = g.tamamlandi ? "✓" : "○";
            console.log(`${durum} ${g.metin} (${g.tarih})`);
        });
    }
}

Kullanım

javascript
const isListesi = new TodoListesi("Haftalık İşler");

const gorev1 = isListesi.gorevEkle("Alışveriş yap");
const gorev2 = isListesi.gorevEkle("Fatura öde");
const gorev3 = isListesi.gorevEkle("Spor yap");

isListesi.gorevTamamla(gorev1.id);
isListesi.listele();
/*
📋 Haftalık İşler

✓ Alışveriş yap (27.01.2024)
○ Fatura öde (27.01.2024)
○ Spor yap (27.01.2024)
*/

isListesi.ozet();
/*
📋 Haftalık İşler
────────────────────
Toplam: 3 görev
Bekleyen: 2
Tamamlanan: 1
────────────────────
*/

Pratik Örnek: Oyuncu Karakteri

javascript
class Karakter {
    constructor(isim, sinif) {
        this.isim = isim;
        this.sinif = sinif;
        this.seviye = 1;
        this.deneyim = 0;
        this.maxCan = 100;
        this.can = 100;
        this.guc = 10;
        this.envanter = [];
    }

    // Savaş metotları
    saldir(hedef) {
        const hasar = Math.floor(Math.random() * this.guc) + 5;
        console.log(`⚔️ ${this.isim}, ${hedef.isim}'e ${hasar} hasar verdi!`);
        hedef.hasarAl(hasar);
        return hasar;
    }

    hasarAl(miktar) {
        this.can -= miktar;
        if (this.can <= 0) {
            this.can = 0;
            console.log(`💀 ${this.isim} yenildi!`);
        } else {
            console.log(`💔 ${this.isim}'in canı: ${this.can}/${this.maxCan}`);
        }
    }

    iyiles(miktar) {
        this.can = Math.min(this.can + miktar, this.maxCan);
        console.log(`💚 ${this.isim} ${miktar} can yeniledi. Can: ${this.can}/${this.maxCan}`);
    }

    // Gelişim metotları
    deneyimKazan(miktar) {
        this.deneyim += miktar;
        console.log(`✨ ${this.isim} ${miktar} XP kazandı!`);

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

    seviyeAtla() {
        this.seviye++;
        this.deneyim = 0;
        this.maxCan += 20;
        this.can = this.maxCan;
        this.guc += 5;
        console.log(`🎉 ${this.isim} seviye atladı! Seviye: ${this.seviye}`);
    }

    // Envanter metotları
    esyaEkle(esya) {
        this.envanter.push(esya);
        console.log(`🎒 ${esya} envantere eklendi.`);
    }

    esyaKullan(esyaAdi) {
        const index = this.envanter.indexOf(esyaAdi);
        if (index > -1) {
            this.envanter.splice(index, 1);
            console.log(`🧪 ${esyaAdi} kullanıldı.`);
            return true;
        }
        console.log(`❌ ${esyaAdi} envanterde yok!`);
        return false;
    }

    // Durum metodu
    durum() {
        console.log(`
╔══════════════════════════╗
║  ${this.isim.padEnd(22)}  ║
╠══════════════════════════╣
║  Sınıf: ${this.sinif.padEnd(17)}║
║  Seviye: ${String(this.seviye).padEnd(16)}║
║  XP: ${this.deneyim}/${this.seviye * 100}${" ".repeat(14 - String(this.deneyim).length - String(this.seviye * 100).length)}║
║  Can: ${this.can}/${this.maxCan}${" ".repeat(15 - String(this.can).length - String(this.maxCan).length)}║
║  Güç: ${String(this.guc).padEnd(18)}║
║  Envanter: ${this.envanter.length} eşya${" ".repeat(9)}║
╚══════════════════════════╝
        `);
    }
}

Kullanım

javascript
const savaşçı = new Karakter("Thorin", "Savaşçı");
const büyücü = new Karakter("Gandalf", "Büyücü");

savaşçı.esyaEkle("Kılıç");
savaşçı.esyaEkle("Kalkan");
savaşçı.esyaEkle("İksir");

savaşçı.saldir(büyücü);  // Thorin, Gandalf'a X hasar verdi!
büyücü.saldir(savaşçı);  // Gandalf, Thorin'e X hasar verdi!

savaşçı.deneyimKazan(50);
savaşçı.deneyimKazan(60);  // Seviye atlama!

savaşçı.durum();

Getter ve Setter

Class içinde özel erişim metotları tanımlayabilirsiniz:

javascript
class Dikdortgen {
    constructor(en, boy) {
        this.en = en;
        this.boy = boy;
    }

    // Getter - özellik gibi erişilir, parantez yok
    get alan() {
        return this.en * this.boy;
    }

    get cevre() {
        return 2 * (this.en + this.boy);
    }

    // Setter - değer atanırken çalışır
    set alan(yeniAlan) {
        // Alanı koruyarak eni ayarla (boy sabit)
        this.en = yeniAlan / this.boy;
    }
}

const dikdortgen = new Dikdortgen(5, 10);

// Getter kullanımı - parantez YOK
console.log(dikdortgen.alan);   // 50
console.log(dikdortgen.cevre);  // 30

// Setter kullanımı
dikdortgen.alan = 100;  // en otomatik 10 olur
console.log(dikdortgen.en);   // 10
console.log(dikdortgen.alan); // 100

Static Metotlar

Static metotlar nesne oluşturmadan, doğrudan class üzerinden çağrılır:

javascript
class Matematik {
    static topla(a, b) {
        return a + b;
    }

    static cikar(a, b) {
        return a - b;
    }

    static rastgele(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    static PI = 3.14159;
}

// Static metotlar - class üzerinden çağrılır
console.log(Matematik.topla(5, 3));       // 8
console.log(Matematik.rastgele(1, 100));  // Rastgele sayı
console.log(Matematik.PI);                // 3.14159

// ❌ Nesne üzerinden çağrılamaz!
const m = new Matematik();
m.topla(5, 3);  // Error!

Static Ne Zaman Kullanılır?

  • Yardımcı fonksiyonlar (helper/utility)
  • Fabrika metotları
  • Sabit değerler
javascript
class Kullanici {
    constructor(ad, email) {
        this.ad = ad;
        this.email = email;
    }

    // Static fabrika metodu
    static misafirOlustur() {
        return new Kullanici("Misafir", "misafir@site.com");
    }

    // Static yardımcı metot
    static emailGecerliMi(email) {
        return email.includes("@");
    }
}

// Fabrika metodu kullanımı
const misafir = Kullanici.misafirOlustur();

// Yardımcı metot kullanımı
console.log(Kullanici.emailGecerliMi("test@mail.com"));  // true

Class Özellikleri (Class Fields)

Modern JavaScript'te özellikleri constructor dışında da tanımlayabilirsiniz:

javascript
class Sayac {
    // Class field - constructor dışında
    deger = 0;
    adim = 1;

    constructor(baslangic = 0) {
        this.deger = baslangic;
    }

    artir() {
        this.deger += this.adim;
    }

    azalt() {
        this.deger -= this.adim;
    }
}

const sayac = new Sayac(10);
sayac.artir();
console.log(sayac.deger);  // 11

Private Alanlar (#)

# ile başlayan özellikler class dışından erişilemez:

javascript
class BankaHesabi {
    #bakiye = 0;  // Private!
    #pin;

    constructor(sahibi, pin) {
        this.sahibi = sahibi;
        this.#pin = pin;
    }

    #pinDogrula(girilenPin) {  // Private metot!
        return this.#pin === girilenPin;
    }

    paraYatir(miktar) {
        this.#bakiye += miktar;
        console.log(`Yatırıldı: ${miktar} TL`);
    }

    paraCek(miktar, pin) {
        if (!this.#pinDogrula(pin)) {
            console.log("❌ Hatalı PIN!");
            return false;
        }
        if (miktar > this.#bakiye) {
            console.log("❌ Yetersiz bakiye!");
            return false;
        }
        this.#bakiye -= miktar;
        console.log(`Çekildi: ${miktar} TL`);
        return true;
    }

    bakiyeSorgula(pin) {
        if (!this.#pinDogrula(pin)) {
            console.log("❌ Hatalı PIN!");
            return null;
        }
        return this.#bakiye;
    }
}

const hesap = new BankaHesabi("Ali", 1234);
hesap.paraYatir(1000);
hesap.paraCek(500, 1234);  // Çekildi: 500 TL
hesap.paraCek(500, 0000);  // ❌ Hatalı PIN!

// ❌ Dışarıdan erişilemez!
console.log(hesap.#bakiye);  // SyntaxError!
console.log(hesap.#pin);     // SyntaxError!

Özet

javascript
class SinifAdi {
    // Class fields (opsiyonel)
    ozellik = "deger";
    #privateOzellik = "gizli";

    // Constructor (zorunlu)
    constructor(param) {
        this.param = param;
    }

    // Instance metotları (prototype'a eklenir)
    normalMetot() {
        return this.param;
    }

    // Getter
    get hesaplananDeger() {
        return this.param * 2;
    }

    // Setter
    set hesaplananDeger(yeniDeger) {
        this.param = yeniDeger / 2;
    }

    // Private metot
    #gizliMetot() {
        // ...
    }

    // Static metot
    static yardimciMetot() {
        // ...
    }
}
ÖzellikAçıklama
classNesne şablonu tanımlar
constructorNesne oluşturulurken çalışır
thisOluşturulan nesneyi ifade eder
MetotlarOtomatik prototype'a eklenir
staticClass üzerinden çağrılan metotlar
get/setÖzel erişim metotları
#Private (gizli) alanlar

Sırada Ne Var?

Class syntax'ını öğrendik. Artık temiz, organize kod yazabiliyoruz.

Bir sonraki makalede class'larla daha fazla pratik yapacağız ve gerçek dünya örnekleri üzerinde çalışacağız.

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 kodunda Constructor Function ve new keyword'ü ile nesne oluşturma örnekleri
JavaScript Dersleri8 dk okuma

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.

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