Tüm blog yazıları

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.

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

Önceki makalede class syntax'ının temellerini öğrendik. Şimdi daha karmaşık ve gerçekçi örneklerle pratik yapma zamanı.

Bu makalede şunları öğreneceğiz:

  • Metotlar arası iletişim (this.metodAdi())
  • Constructor içinde metot çağırma
  • Kod tekrarını azaltma (DRY prensibi)
  • Gerçek dünya senaryoları

Metottan Metot Çağırma

Bir class içindeki metot, aynı class'taki başka bir metodu this ile çağırabilir:

javascript
class Hesaplayici {
    constructor(sayi) {
        this.sayi = sayi;
    }

    karesi() {
        return this.sayi * this.sayi;
    }

    kupu() {
        // karesi() metodunu kullanarak küpü hesapla
        return this.karesi() * this.sayi;
    }

    ussu(n) {
        let sonuc = 1;
        for (let i = 0; i < n; i++) {
            sonuc *= this.sayi;
        }
        return sonuc;
    }

    // Birden fazla metodu birleştir
    ozet() {
        return `
Sayı: ${this.sayi}
Karesi: ${this.karesi()}
Küpü: ${this.kupu()}
4. Kuvveti: ${this.ussu(4)}
        `;
    }
}

const hesap = new Hesaplayici(5);
console.log(hesap.ozet());
/*
Sayı: 5
Karesi: 25
Küpü: 125
4. Kuvveti: 625
*/

Constructor İçinde Metot Çağırma

Constructor'da başka metotları çağırarak başlangıç hesaplamaları yapabilirsiniz:

javascript
class Urun {
    constructor(ad, fiyat, kdvOrani = 20) {
        this.ad = ad;
        this.fiyat = fiyat;
        this.kdvOrani = kdvOrani;

        // Constructor içinde metot çağır
        this.kdvHesapla();
    }

    kdvHesapla() {
        this.kdv = this.fiyat * (this.kdvOrani / 100);
        this.toplamFiyat = this.fiyat + this.kdv;
    }

    fiyatGuncelle(yeniFiyat) {
        this.fiyat = yeniFiyat;
        // Fiyat değişince KDV'yi yeniden hesapla
        this.kdvHesapla();
    }

    bilgi() {
        console.log(`
${this.ad}
─────────────────
Fiyat: ${this.fiyat} TL
KDV (%${this.kdvOrani}): ${this.kdv} TL
Toplam: ${this.toplamFiyat} TL
        `);
    }
}

const laptop = new Urun("MacBook Pro", 50000);
laptop.bilgi();
/*
MacBook Pro
─────────────────
Fiyat: 50000 TL
KDV (%20): 10000 TL
Toplam: 60000 TL
*/

laptop.fiyatGuncelle(45000);
laptop.bilgi();
// Toplam otomatik güncellenir: 54000 TL

Pratik Örnek: Alışveriş Sepeti

javascript
class Sepet {
    constructor() {
        this.urunler = [];
        this.indirimKodu = null;
        this.indirimOrani = 0;
    }

    // Ürün ekleme
    urunEkle(ad, fiyat, adet = 1) {
        const mevcutUrun = this.urunler.find(u => u.ad === ad);

        if (mevcutUrun) {
            mevcutUrun.adet += adet;
            console.log(`${ad} adedi güncellendi: ${mevcutUrun.adet}`);
        } else {
            this.urunler.push({ ad, fiyat, adet });
            console.log(`${ad} sepete eklendi.`);
        }

        return this;
    }

    // Ürün çıkarma
    urunCikar(ad) {
        const index = this.urunler.findIndex(u => u.ad === ad);
        if (index > -1) {
            const silinen = this.urunler.splice(index, 1)[0];
            console.log(`${silinen.ad} sepetten çıkarıldı.`);
        }
        return this;
    }

    // Adet güncelleme
    adetGuncelle(ad, yeniAdet) {
        const urun = this.urunler.find(u => u.ad === ad);
        if (urun) {
            if (yeniAdet <= 0) {
                this.urunCikar(ad);
            } else {
                urun.adet = yeniAdet;
            }
        }
        return this;
    }

    // İndirim kodu uygulama
    indirimUygula(kod) {
        const indirimler = {
            "YAZ10": 10,
            "OZEL20": 20,
            "SUPER30": 30
        };

        if (indirimler[kod]) {
            this.indirimKodu = kod;
            this.indirimOrani = indirimler[kod];
            console.log(`✅ %${this.indirimOrani} indirim uygulandı!`);
        } else {
            console.log("❌ Geçersiz indirim kodu!");
        }
        return this;
    }

    // Ara toplam (indirim öncesi)
    araToplam() {
        return this.urunler.reduce((toplam, urun) => {
            return toplam + (urun.fiyat * urun.adet);
        }, 0);
    }

    // İndirim tutarı
    indirimTutari() {
        return this.araToplam() * (this.indirimOrani / 100);
    }

    // Genel toplam
    genelToplam() {
        return this.araToplam() - this.indirimTutari();
    }

    // Sepet boş mu?
    bosMu() {
        return this.urunler.length === 0;
    }

    // Sepeti temizle
    temizle() {
        this.urunler = [];
        this.indirimKodu = null;
        this.indirimOrani = 0;
        console.log("Sepet temizlendi.");
        return this;
    }

    // Sepeti göster
    goster() {
        if (this.bosMu()) {
            console.log("🛒 Sepetiniz boş.");
            return;
        }

        console.log("\n🛒 SEPETİNİZ");
        console.log("═".repeat(40));

        this.urunler.forEach((urun, index) => {
            const satirToplam = urun.fiyat * urun.adet;
            console.log(`${index + 1}. ${urun.ad}`);
            console.log(`   ${urun.adet} x ${urun.fiyat} TL = ${satirToplam} TL`);
        });

        console.log("─".repeat(40));
        console.log(`Ara Toplam: ${this.araToplam()} TL`);

        if (this.indirimOrani > 0) {
            console.log(`İndirim (${this.indirimKodu}): -${this.indirimTutari()} TL`);
        }

        console.log("═".repeat(40));
        console.log(`GENEL TOPLAM: ${this.genelToplam()} TL`);
        console.log();
    }
}

Kullanım

javascript
const sepet = new Sepet();

// Method chaining ile ürün ekleme
sepet
    .urunEkle("iPhone 15", 55000)
    .urunEkle("AirPods Pro", 8000)
    .urunEkle("iPhone Kılıfı", 500, 2)
    .urunEkle("AirPods Pro", 8000);  // Adet artar

sepet.goster();
/*
🛒 SEPETİNİZ
════════════════════════════════════════
1. iPhone 15
   1 x 55000 TL = 55000 TL
2. AirPods Pro
   2 x 8000 TL = 16000 TL
3. iPhone Kılıfı
   2 x 500 TL = 1000 TL
────────────────────────────────────────
Ara Toplam: 72000 TL
════════════════════════════════════════
GENEL TOPLAM: 72000 TL
*/

sepet.indirimUygula("OZEL20");
sepet.goster();
// GENEL TOPLAM: 57600 TL (20% indirimli)

Pratik Örnek: Müzik Çalar

javascript
class MuzikCalar {
    constructor() {
        this.sarkilar = [];
        this.suankiIndex = 0;
        this.caliyorMu = false;
        this.ses = 50;
        this.tekrar = false;
        this.karistir = false;
    }

    // Şarkı ekleme
    sarkiEkle(ad, sanatci, sure) {
        this.sarkilar.push({
            id: Date.now(),
            ad,
            sanatci,
            sure,  // saniye cinsinden
            eklenme: new Date()
        });
        console.log(`♪ "${ad}" eklendi.`);
        return this;
    }

    // Mevcut şarkı
    suankiSarki() {
        if (this.sarkilar.length === 0) return null;
        return this.sarkilar[this.suankiIndex];
    }

    // Süreyi formatla (120 -> "2:00")
    sureFormatla(saniye) {
        const dk = Math.floor(saniye / 60);
        const sn = saniye % 60;
        return `${dk}:${sn.toString().padStart(2, "0")}`;
    }

    // Çal/Duraklat
    calDuraklat() {
        if (this.sarkilar.length === 0) {
            console.log("Liste boş!");
            return this;
        }

        this.caliyorMu = !this.caliyorMu;
        const sarki = this.suankiSarki();

        if (this.caliyorMu) {
            console.log(`▶️ Çalıyor: "${sarki.ad}" - ${sarki.sanatci}`);
        } else {
            console.log(`⏸️ Duraklatıldı: "${sarki.ad}"`);
        }
        return this;
    }

    // Sonraki şarkı
    sonraki() {
        if (this.sarkilar.length === 0) return this;

        if (this.karistir) {
            this.suankiIndex = Math.floor(Math.random() * this.sarkilar.length);
        } else {
            this.suankiIndex = (this.suankiIndex + 1) % this.sarkilar.length;
        }

        const sarki = this.suankiSarki();
        console.log(`⏭️ Sonraki: "${sarki.ad}" - ${sarki.sanatci}`);

        if (this.caliyorMu) {
            console.log(`▶️ Çalıyor...`);
        }
        return this;
    }

    // Önceki şarkı
    onceki() {
        if (this.sarkilar.length === 0) return this;

        this.suankiIndex = this.suankiIndex === 0
            ? this.sarkilar.length - 1
            : this.suankiIndex - 1;

        const sarki = this.suankiSarki();
        console.log(`⏮️ Önceki: "${sarki.ad}" - ${sarki.sanatci}`);
        return this;
    }

    // Ses ayarı
    sesAyarla(deger) {
        this.ses = Math.max(0, Math.min(100, deger));
        const sesBar = "█".repeat(this.ses / 10) + "░".repeat(10 - this.ses / 10);
        console.log(`🔊 Ses: [${sesBar}] ${this.ses}%`);
        return this;
    }

    sesAc(miktar = 10) {
        return this.sesAyarla(this.ses + miktar);
    }

    sesKis(miktar = 10) {
        return this.sesAyarla(this.ses - miktar);
    }

    // Tekrar modu
    tekrarToggle() {
        this.tekrar = !this.tekrar;
        console.log(`🔁 Tekrar: ${this.tekrar ? "Açık" : "Kapalı"}`);
        return this;
    }

    // Karıştır modu
    karistirToggle() {
        this.karistir = !this.karistir;
        console.log(`🔀 Karıştır: ${this.karistir ? "Açık" : "Kapalı"}`);
        return this;
    }

    // Listeyi göster
    listeGoster() {
        console.log("\n🎵 ÇALMA LİSTESİ");
        console.log("─".repeat(50));

        if (this.sarkilar.length === 0) {
            console.log("Liste boş.");
            return this;
        }

        this.sarkilar.forEach((sarki, index) => {
            const aktif = index === this.suankiIndex;
            const isaret = aktif ? (this.caliyorMu ? "▶️" : "⏸️") : "  ";
            console.log(`${isaret} ${index + 1}. ${sarki.ad} - ${sarki.sanatci} (${this.sureFormatla(sarki.sure)})`);
        });

        console.log("─".repeat(50));
        console.log(`Toplam: ${this.sarkilar.length} şarkı`);
        console.log();
        return this;
    }

    // Durum göster
    durum() {
        const sarki = this.suankiSarki();
        if (!sarki) {
            console.log("Şarkı yok.");
            return this;
        }

        console.log(`
╔══════════════════════════════════════╗
║  ${this.caliyorMu ? "▶️ Çalıyor" : "⏸️ Duraklatıldı"}
║  ${sarki.ad.substring(0, 30).padEnd(30)}
║  ${sarki.sanatci.substring(0, 30).padEnd(30)}
║  ${this.sureFormatla(sarki.sure)}
╟──────────────────────────────────────╢
║  🔊 ${this.ses}%  🔁 ${this.tekrar ? "On" : "Off"}  🔀 ${this.karistir ? "On" : "Off"}
╚══════════════════════════════════════╝
        `);
        return this;
    }
}

Kullanım

javascript
const calar = new MuzikCalar();

calar
    .sarkiEkle("Yalnızlık", "Tarkan", 245)
    .sarkiEkle("Ağlama", "Sezen Aksu", 312)
    .sarkiEkle("Firuze", "Sezen Aksu", 278)
    .sarkiEkle("Kuzu Kuzu", "Tarkan", 198);

calar.listeGoster();
calar.calDuraklat();  // Çalmaya başla
calar.durum();

calar.sonraki();
calar.sesAc();
calar.sesAc();

calar.karistirToggle();
calar.sonraki();  // Rastgele şarkıya geç

Pratik Örnek: Form Doğrulama

javascript
class FormDogrulayici {
    constructor() {
        this.kurallar = {};
        this.hatalar = {};
    }

    // Alan için kural ekle
    alan(alanAdi) {
        this.kurallar[alanAdi] = [];
        this.hatalar[alanAdi] = [];

        // Method chaining için helper nesne döndür
        const kuralEkleyici = {
            zorunlu: (mesaj = `${alanAdi} zorunludur.`) => {
                this.kurallar[alanAdi].push({
                    tip: "zorunlu",
                    mesaj,
                    dogrula: (deger) => deger !== undefined && deger !== ""
                });
                return kuralEkleyici;
            },

            minUzunluk: (min, mesaj = `${alanAdi} en az ${min} karakter olmalı.`) => {
                this.kurallar[alanAdi].push({
                    tip: "minUzunluk",
                    mesaj,
                    dogrula: (deger) => deger && deger.length >= min
                });
                return kuralEkleyici;
            },

            maxUzunluk: (max, mesaj = `${alanAdi} en fazla ${max} karakter olmalı.`) => {
                this.kurallar[alanAdi].push({
                    tip: "maxUzunluk",
                    mesaj,
                    dogrula: (deger) => !deger || deger.length <= max
                });
                return kuralEkleyici;
            },

            email: (mesaj = "Geçerli bir email adresi girin.") => {
                this.kurallar[alanAdi].push({
                    tip: "email",
                    mesaj,
                    dogrula: (deger) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(deger)
                });
                return kuralEkleyici;
            },

            sayi: (mesaj = `${alanAdi} sayı olmalı.`) => {
                this.kurallar[alanAdi].push({
                    tip: "sayi",
                    mesaj,
                    dogrula: (deger) => !isNaN(deger) && deger !== ""
                });
                return kuralEkleyici;
            },

            min: (minDeger, mesaj = `${alanAdi} en az ${minDeger} olmalı.`) => {
                this.kurallar[alanAdi].push({
                    tip: "min",
                    mesaj,
                    dogrula: (deger) => Number(deger) >= minDeger
                });
                return kuralEkleyici;
            },

            max: (maxDeger, mesaj = `${alanAdi} en fazla ${maxDeger} olmalı.`) => {
                this.kurallar[alanAdi].push({
                    tip: "max",
                    mesaj,
                    dogrula: (deger) => Number(deger) <= maxDeger
                });
                return kuralEkleyici;
            },

            eslesme: (digerAlan, mesaj = `${alanAdi} ile ${digerAlan} eşleşmeli.`) => {
                this.kurallar[alanAdi].push({
                    tip: "eslesme",
                    mesaj,
                    digerAlan,
                    dogrula: (deger, tumVeri) => deger === tumVeri[digerAlan]
                });
                return kuralEkleyici;
            },

            ozel: (dogrulaFn, mesaj) => {
                this.kurallar[alanAdi].push({
                    tip: "ozel",
                    mesaj,
                    dogrula: dogrulaFn
                });
                return kuralEkleyici;
            }
        };

        return kuralEkleyici;
    }

    // Doğrulama yap
    dogrula(veri) {
        this.hatalar = {};
        let gecerli = true;

        for (const alanAdi in this.kurallar) {
            this.hatalar[alanAdi] = [];
            const deger = veri[alanAdi];
            const alanKurallari = this.kurallar[alanAdi];

            for (const kural of alanKurallari) {
                const sonuc = kural.dogrula(deger, veri);
                if (!sonuc) {
                    this.hatalar[alanAdi].push(kural.mesaj);
                    gecerli = false;
                }
            }
        }

        return gecerli;
    }

    // Hataları al
    hatalariAl() {
        const sonuc = {};
        for (const alan in this.hatalar) {
            if (this.hatalar[alan].length > 0) {
                sonuc[alan] = this.hatalar[alan];
            }
        }
        return sonuc;
    }

    // Hataları göster
    hatalariGoster() {
        const hatalar = this.hatalariAl();

        if (Object.keys(hatalar).length === 0) {
            console.log("✅ Form geçerli!");
            return;
        }

        console.log("❌ Form hataları:");
        for (const alan in hatalar) {
            hatalar[alan].forEach(hata => {
                console.log(`  • ${hata}`);
            });
        }
    }
}

Kullanım

javascript
const kayitFormu = new FormDogrulayici();

// Kuralları tanımla
kayitFormu
    .alan("kullaniciAdi")
        .zorunlu()
        .minUzunluk(3)
        .maxUzunluk(20);

kayitFormu
    .alan("email")
        .zorunlu()
        .email();

kayitFormu
    .alan("sifre")
        .zorunlu()
        .minUzunluk(8, "Şifre en az 8 karakter olmalı.");

kayitFormu
    .alan("sifreTekrar")
        .zorunlu()
        .eslesme("sifre", "Şifreler eşleşmiyor!");

kayitFormu
    .alan("yas")
        .zorunlu()
        .sayi()
        .min(18, "18 yaşından büyük olmalısınız.")
        .max(100);

// Test - Hatalı veri
const hataliVeri = {
    kullaniciAdi: "ab",
    email: "gecersiz-email",
    sifre: "123",
    sifreTekrar: "456",
    yas: "15"
};

kayitFormu.dogrula(hataliVeri);
kayitFormu.hatalariGoster();
/*
❌ Form hataları:
  • kullaniciAdi en az 3 karakter olmalı.
  • Geçerli bir email adresi girin.
  • Şifre en az 8 karakter olmalı.
  • Şifreler eşleşmiyor!
  • 18 yaşından büyük olmalısınız.
*/

// Test - Geçerli veri
const gecerliVeri = {
    kullaniciAdi: "ahmet123",
    email: "ahmet@mail.com",
    sifre: "guvenli123",
    sifreTekrar: "guvenli123",
    yas: "25"
};

kayitFormu.dogrula(gecerliVeri);
kayitFormu.hatalariGoster();
// ✅ Form geçerli!

Özet: Class'larda İleri Teknikler

TeknikAçıklamaÖrnek
Metottan metot çağırmathis.metodAdi() ilethis.hesapla()
Constructor'da metotBaşlangıç hesaplamalarıthis.initialize()
Method chainingreturn this ileobj.ekle().sil().goster()
Helper metotlarİç kullanım için_formatla()
Hesaplanan özelliklerConstructor'da ayarlathis.toplam = this.hesapla()

Sırada Ne Var?

Class'larla çeşitli pratik uygulamalar yaptık. Artık gerçek projelerde class kullanabilirsiniz.

Bir sonraki ve son makalede extends ve super keyword'lerini öğreneceğiz - class'lar arası miras (inheritance) ve kod paylaşımı.

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 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