Bu doküman, ileri düzey bir JavaScript eğitim programının detaylı müfredatını içeriyor. İstediğiniz kurallar doğrultusunda, zaman sürelerini eklemeden, "Öğrenecekleriniz" bölümünü ve her konuyu alt başlıklarıyla birlikte hiçbir özet yapmadan, detaylı açıklamalar, teorik altyapılar, kod örnekleri ve pratik uygulamalarla ele alıyoruz.

Aşağıda müfredatın ilk büyük bölümü yer almaktadır. İçeriğin derinliği ve detay seviyesi çok yüksek olduğu için anlatım parça parça ilerleyecektir. Yarıda kaldığımda sizi bilgilendireceğim.


"Öğrenecekleriniz" Paragrafının Açıklaması

Bu bölüm, kursun öğrencilere kazandırmayı hedeflediği ana yetenekleri ve ileri düzey vizyonu özetler.


1. BÖLÜM: Object Oriented JavaScript (Nesne Yönelimli JavaScript)

Nesne Yönelimli Programlama (OOP), gerçek dünyadaki varlıkları yazılım dünyasında nesneler (objects) olarak modelleme biçimidir. JavaScript, prototip tabanlı bir OOP dilidir ancak modern söz diziminde sınıf (class) yapılarını da tam olarak destekler.

Working With Plain Old JavaScript Objects (Düz Eski JavaScript Nesneleriyle Çalışmak)

JavaScript'te en temel nesne oluşturma yöntemi süslü parantezler {} kullanarak yapılan nesne sabitleridir (Object Literals). Bu nesneler key-value (anahtar-değer) çiftlerinden oluşur.

Kod Örneği:

// Düz bir nesne tanımlama

const araba = {

  marka: "Opel",

  model: "Astra",

  yil: 2022

};

 

// Özelliklere erişim ve değiştirme

araba.renk = "Kırmızı"; // Dinamik ekleme

console.log(araba.marka); // "Opel"

Mixing Data & Functions With Objects (Veri ve Fonksiyonları Nesnelerle Karıştırmak)

Bir nesnenin içerisine sadece veri (özellikler) değil, o veriyi işleyecek fonksiyonlar da (metotlar) eklenebilir.

Kod Örneği:

const kullanici = {

  isim: "Ahmet",

  soyisim: "Yılmaz",

  tamIsimGoster: function() {

    return `${this.isim} ${this.soyisim}`;

  }

};

 

console.log(kullanici.tamIsimGoster()); // "Ahmet Yılmaz"

Class Basics (Sınıf Temelleri)

Sınıflar, benzer özelliklere ve metotlara sahip olacak nesneleri üretmek için kullanılan şablonlardır (mavi reçetelerdir).

Kod Örneği:

class Canli {

  nefesAl() {

    console.log("Nefes alınıyor...");

  }

}

 

const insan = new Canli();

insan.nefesAl(); // "Nefes alınıyor..."

Constructors (Yapıcı Fonksiyonlar)

Bir sınıftan new anahtar kelimesiyle yeni bir nesne (örnek/instance) oluşturulduğu an otomatik olarak çalışan özel metottur.

Kod Örneği:

class Kitap {

  constructor(ad, yazar) {

    this.ad = ad;

    this.yazar = yazar;

  }

}

 

const kitap1 = new Kitap("Nutuk", "Mustafa Kemal Atatürk");

console.log(kitap1.ad); // "Nutuk"

Practice Time: Bank Account (Uygulama Zamanı: Banka Hesabı)

Sınıf, yapıcı fonksiyon ve temel nesne yapısını birleştiren bir banka hesabı simülasyonu yapalım.

Uygulama Kodu:

class BankaHesabi {

  constructor(sahip, bakiye = 0) {

    this.sahip = sahip;

    this.bakiye = bakiye;

  }

 

  paraYatir(miktar) {

    this.bakiye += miktar;

    console.log(`${miktar} TL yatırıldı. Güncel bakiye: ${this.bakiye} TL`);

  }

 

  paraCek(miktar) {

    if (miktar > this.bakiye) {

      console.log("Yetersiz bakiye!");

    } else {

      this.bakiye -= miktar;

      console.log(`${miktar} TL çekildi. Kalan bakiye: ${this.bakiye} TL`);

    }

  }

}

 

const ahmetinHesabi = new BankaHesabi("Ahmet Yılmaz", 500);

ahmetinHesabi.paraYatir(200); // 200 TL yatırıldı. Güncel bakiye: 700 TL

ahmetinHesabi.paraCek(1000);  // Yetersiz bakiye!

ahmetinHesabi.paraCek(300);   // 300 TL çekildi. Kalan bakiye: 400 TL

Instance Methods (Örnek Metotları)

Bir sınıftan üretilen her bir nesnenin (instance) doğrudan erişebileceği ve üzerinde işlem yapabileceği fonksiyonlardır.

Inheritance Basics (Kalıtım Temelleri)

Bir sınıfın, başka bir sınıfın özelliklerini ve metotlarını devralarak kendi bünyesine katmasıdır. extends anahtar kelimesiyle sağlanır.

Kod Örneği:

class Hayvan {

  constructor(isim) {

    this.isim = isim;

  }

  sesCikar() {

    console.log("Bir ses çıkarıyor...");

  }

}

 

class Kopek extends Hayvan {

  havla() {

    console.log("Hav! Hav!");

  }

}

 

const kopek = new Kopek("Karabaş");

kopek.sesCikar(); // "Bir ses çıkarıyor..." (Üst sınıftan geldi)

kopek.havla();    // "Hav! Hav!" (Kendi metodu)

The Super Keyword (super Anahtar Kelimesi)

Alt sınıfta, üst sınıfın constructor'ını veya metotlarını çağırmak için kullanılan anahtar kelimedir.

Kod Örneği:

class Calisan {

  constructor(isim, maas) {

    this.isim = isim;

    this.maas = maas;

  }

}

 

class Yonetici extends Calisan {

  constructor(isim, maas, departman) {

    super(isim, maas); // Üst sınıfın constructor'ını tetikler

    this.departman = departman;

  }

}

 

const mudur = new Yonetici("Zeynep", 45000, "BT");

console.log(mudur.isim, mudur.departman); // "Zeynep BT"

Static Properties (Statik Özellikler)

Nesneye değil, doğrudan sınıfın kendisine ait olan değişkenlerdir.

Kod Örneği:

class Ayarlar {

  static UYGULAMA_ADI = "BenimUygulamam";

}

 

const config = new Ayarlar();

console.log(config.UYGULAMA_ADI); // undefined (Nesneden erişilemez)

console.log(Ayarlar.UYGULAMA_ADI); // "BenimUygulamam" (Sınıftan erişilir)

Static Methods (Statik Metotlar)

Doğrudan sınıf üzerinden çağrılan, nesne oluşturulmasını gerektirmeyen metotlardır.

Kod Örneği:

class Matematik {

  static topla(a, b) {

    return a + b;

  }

}

 

console.log(Matematik.topla(10, 20)); // 30

Use Cases For Static Methods (Statik Metotlar İçin Kullanım Senaryoları)

Uygulama Kodu (Fabrika Metodu):

class Kullanici {

  constructor(isim, rol) {

    this.isim = isim;

    this.rol = rol;

  }

 

  // Statik Fabrika Metodu

  static anonimYarat() {

    return new Kullanici("Misafir Kullanıcı", "Ziyaretçi");

  }

}

 

const misafir = Kullanici.anonimYarat();

console.log(misafir.isim); // "Misafir Kullanıcı"

Ebook & ArrayUtils Exercises (E-Kitap ve Dizi Araçları Egzersizleri)

Sınıfları, statik metotları ve kalıtımı pekiştirmek için iki ayrı egzersiz kodu kuralım.

Uygulama Kodu 1 (ArrayUtils Egzersizi):

class DiziAraclari {

  // Verilen dizinin ortalamasını alan statik metot

  static ortalamaBul(dizi) {

    const toplam = dizi.reduce((acc, curr) => acc + curr, 0);

    return toplam / dizi.length;

  }

}

 

console.log(DiziAraclari.ortalamaBul([10, 20, 30, 40])); // 25

Uygulama Kodu 2 (Ebook Kalıtım Egzersizi):

class Urun {

  constructor(baslik, fiyat) {

    this.baslik = baslik;

    this.fiyat = fiyat;

  }

}

 

class EKitap extends Urun {

  constructor(baslik, fiyat, dosyaBoyutu) {

    super(baslik, fiyat);

    this.dosyaBoyutu = dosyaBoyutu;

  }

}

 

const pdfKitap = new EKitap("JS Rehberi", 150, "5MB");

console.log(pdfKitap.baslik, pdfKitap.dosyaBoyutu); // "JS Rehberi 5MB"


2. BÖLÜM: OOP: Newer Features in JavaScript (OOP: JavaScript'teki Yeni Özellikler)

Modern JavaScript standartlarıyla (ES2022 ve civarı) birlikte nesne yönelimli yapılara güvenlik ve veri kapsülleme adına kritik yenilikler gelmiştir.

Getters (Alıcılar)

Bir nesnenin özelliğini okumaya çalışırken arka planda bir fonksiyon çalıştırıp geriye dinamik bir değer dönme işlemidir. get kelimesiyle tanımlanır.

Kod Örneği:

class Dikdortgen {

  constructor(en, boy) {

    this.en = en;

    this.boy = boy;

  }

 

  // Getter

  get alan() {

    return this.en * this.boy;

  }

}

 

const kare = new Dikdortgen(5, 5);

console.log(kare.alan); // 25 (Fonksiyon gibi parantez açıp kapatmadık!)

Setters (Ayarlayıcılar)

Bir nesne özelliğine yeni bir değer atanmaya çalışıldığında devreye giren ve atanan değeri kontrol/filtre mekanizmasından geçiren yapılardır. set kelimesiyle tanımlanır.

Kod Örneği:

class Sicaklik {

  constructor(santigrat) {

    this._santigrat = santigrat; // İç değişken

  }

 

  set fahrenheit(deger) {

    this._santigrat = (deger - 32) * 5 / 9;

  }

 

  get santigrat() {

    return this._santigrat;

  }

}

 

const hava = new Sicaklik(0);

hava.fahrenheit = 32; // Set tetiklendi

console.log(hava.santigrat); // 0

Practice Time: Getters and Setters (Uygulama Zamanı)

Bir kullanıcı profilindeki yaş ve e-posta kontrolünü kapsayan güvenli yapı tasarlayalım.

Uygulama Kodu:

class Profil {

  constructor(isim, yas) {

    this.isim = isim;

    this.yas = yas; // setter tetiklenecek

  }

 

  get yas() {

    return this._yas;

  }

 

  set yas(yeniYas) {

    if (yeniYas < 0) {

      console.log("Hata: Yaş değeri negatif olamaz!");

      this._yas = 0;

    } else {

      this._yas = yeniYas;

    }

  }

}

 

const user = new Profil("Can", -5); // "Hata: Yaş değeri negatif olamaz!"

console.log(user.yas); // 0

Public Fields (Açık Alanlar)

Constructor dışında, sınıf gövdesinde doğrudan tanımlanan ve dışarıdan tamamen erişilebilen sınıf özellikleridir.

Kod Örneği:

class SkorBord {

  skor = 0; // Public Field

  durum = "Başlamadı";

 

  puanKazan() {

    this.skor++;

  }

}

 

const mac = new SkorBord();

mac.puanKazan();

console.log(mac.skor); // 1

Private Fields (Gizli Alanlar)

Sınıf dışından erişilmesi tamamen engellenmiş, sadece sınıfın kendi içindeki metotlar tarafından okunup değiştirilebilen özelliklerdir. # sembolü ile tanımlanır.

Kod Örneği:

class Kasa {

  #sifre; // Private Field ilanı

 

  constructor(ilkSifre) {

    this.#sifre = ilkSifre;

  }

 

  sifreDegistir(eskiSifre, yeniSifre) {

    if (this.#sifre === eskiSifre) {

      this.#sifre = yeniSifre;

      console.log("Şifre güncellendi.");

    } else {

      console.log("Eski şifre yanlış!");

    }

  }

}

 

const kasa = new Kasa("1234");

// console.log(kasa.#sifre); // HATA! SyntaxError verir dışarıdan okunamaz.

kasa.sifreDegistir("1234", "5678"); // "Şifre güncellendi."

Private Methods (Gizli Metotlar)

Sadece sınıfın kendi içindeki diğer metotlar tarafından çağrılabilen, dış dünyaya kapatılmış fonksiyonlardır. Yine # ile başlarlar.

Kod Örneği:

class BankaSistemi {

  #logTut(mesaj) { // Gizli Metot

    console.log(`[LOG - ${new Date().toLocaleTimeString()}]: ${mesaj}`);

  }

 

  islemYap() {

    // İçeriden güvenle çağrılır

    this.#logTut("Kullanıcı işlem gerçekleştirdi.");

  }

}

 

const sistem = new BankaSistemi();

sistem.islemYap();

// sistem.#logTut("Sızma testi"); // HATA! Sınıf dışından ulaşılamaz.

ES2022 Static Initialization Blocks (Statik İlklendirme Blokları)

Statik özellikleri (static properties) başlatırken birden fazla satırdan oluşan, mantıksal veya hata yönetimli (try-catch) karmaşık işlemleri gerçekleştirmeyi sağlayan kod bloklarıdır.

Kod Örneği:

class VeriTabani Baglantisi {

  static baglantiDurumu;

 

  // Statik Başlatma Bloğu

  static {

    try {

      // Karmaşık kurulum adımları simüle ediliyor

      let baglandi mi = true;

      if (baglandi mi) {

        this.baglantiDurumu = "Aktif";

      } else {

        this.baglantiDurumu = "Pasif";

      }

    } catch (e) {

      this.baglantiDurumu = "Hata";

    }

  }

}

 

console.log(VeriTabani Baglantisi.baglantiDurumu); // "Aktif"


3. BÖLÜM: The Mysterious Keyword "This" (Gizemli "This" Anahtar Kelimesi)

JavaScript'te this, fonksiyonun nasıl yazıldığına değil, nasıl çağrıldığına bağlı olarak dinamik şekilde değişen, mevcut yürütme bağlamını (execution context) işaret eden özel bir kelimedir.

Introducing This & The Mystery of The Keyword This (This ile Tanışma ve Gizemi)

Bir fonksiyon çalıştırıldığında, o anki işlem alanını temsil eden bir nesneye ihtiyaç duyar. İşte this, o nesneyi tutar. Dinamik yapısı nedeniyle JavaScript dünyasında en çok kafa karıştıran konulardan biridir.

Global Objects and This (Küresel Nesneler ve This)

Eğer bir fonksiyon hiçbir nesneye bağlı olmadan, düz bir şekilde global alanda çağrılırsa this global nesneye yönlenir.

Kod Örneği:

function kontrolEt() {

  console.log(this);

}

 

kontrolEt(); // Tarayıcıda 'window' nesnesini basar.

 

function katiModKontrol() {

  "use strict";

  console.log(this);

}

katiModKontrol(); // 'undefined' basar.

The "Left Of The Dot" Rule (Noktanın Solundaki Kural)

Bir fonksiyon (metot) bir nesne üzerinden çağrılıyorsa, fonksiyonun içindeki this anahtar kelimesi nokta işaretinin solunda yer alan nesneyi gösterir.

Kod Örneği:

const dukkan = {

  isim: "Merkez Şube",

  selamla: function() {

    console.log(`Hoş geldiniz, burası ${this.isim}`);

  }

};

 

dukkan.selamla(); // Noktanın solunda 'dukkan' var. This = dukkan.

// Çıktı: "Hoş geldiniz, burası Merkez Şube"

This and Classes (Sınıflar ve This)

Sınıfların içindeki metotlarda kullanılan this, o sınıftan new kelimesiyle üretilen yeni nesne örneğinin (instance) kendisini hedefler.

Kod Örneği:

class Oyuncu {

  constructor(ad) {

    this.ad = ad; // This, yeni üretilecek nesnedir.

  }

}

const p1 = new Oyuncu("Hakan");

The Call Method (call Metodu)

Bir fonksiyonu, içerisindeki this bağlamını el ile (manuel) değiştirerek ve parametreleri tek tek virgülle göndererek hemen çalıştırmaya yarayan yerleşik metottur.

Kod Örneği:

function puanDurumu(MacSayisi, GolSayisi) {

  console.log(`${this.isim} -> Maç: ${MacSayisi}, Gol: ${GolSayisi}`);

}

 

const forvet = { isim: "Icardi" };

 

// puanDurumu içindeki 'this' artık 'forvet' nesnesi olacak

puanDurumu.call(forvet, 10, 8); // "Icardi -> Maç: 10, Gol: 8"

The Apply Method (apply Metodu)

call metodu ile tamamen aynı işi yapar; tek farkı fonksiyona gönderilecek parametrelerin tek tek değil, bir dizi (array) halinde iletilmesidir.

Kod Örneği:

const defans = { isim: "Nelsson" };

 

// Parametreleri dizi olarak yolluyoruz

puanDurumu.apply(defans, [12, 1]); // "Nelsson -> Maç: 12, Gol: 1"

The Bind Method (bind Metodu)

Fonksiyonu hemen çalıştırmaz. İçerisindeki this kelimesini kalıcı olarak belirlediğimiz bir nesneye bağlayarak bize yeni bir fonksiyon kopyası verir.

Kod Örneği:

const kaleci = { isim: "Muslera" };

 

// Kaleci nesnesine kilitlenmiş yeni bir fonksiyon üretiyoruz

const kaleciPuani = puanDurumu.bind(kaleci);

 

// İlerleyen zamanlarda istediğimiz an çağırabiliriz

kaleciPuani(15, 0); // "Muslera -> Maç: 15, Gol: 0"

Binding Arguments (Argümanları Bağlamak)

bind metodu sadece this bağlamını kilitlemekle kalmaz, fonksiyonun alacağı ilk parametreleri de önceden sabitleyebilir. Buna fonksiyonel programlamada kısmi uygulama (partial application) da denir.

Kod Örneği:

function vergiHesapla(oran, miktar) {

  return miktar * oran;

}

 

// Oran parametresini %18 (0.18) olarak kalıcı kilitliyoruz

const kdvHesapla = vergiHesapla.bind(null, 0.18);

 

// Artık sadece miktar girmemiz yeterli

console.log(kdvHesapla(100)); // 18

console.log(kdvHesapla(500)); // 90

Bind With Event Listeners (Olay Dinleyicilerle Bind Kullanımı)

HTML elementlerine olay dinleyici (event listener) eklendiğinde, callback fonksiyonunun içindeki this varsayılan olarak olayı tetikleyen HTML elementine dönüşür. Sınıf metotlarımızın bozulmaması için bind ile sabitleme yaparız.

Uygulama Kodu:

class Sayac Butonu {

  constructor() {

    this.tiklama Sayisi = 0;

    this.button = document.createElement("button");

    this.button.textContent = "Tıkla";

   

    // bind(this) yapmazsak, tikla metodu içindeki this buton elementini gösterir ve hata alırız.

    this.button.addEventListener("click", this.tikla.bind(this));

    document.body.appendChild(this.button);

  }

 

  tikla() {

    this.tiklama Sayisi++;

    this.button.textContent = `Tıklama: ${this.tiklama Sayisi}`;

  }

}

Bind With Timers (Zamanlayıcılarla Bind Kullanımı)

setTimeout veya setInterval gibi asenkron zamanlayıcılar çalıştırıldığında, içlerindeki fonksiyonlar global bağlamda tetiklenir ve this kaybedilir. Bunu önlemek için fonksiyonu bağlamamız gerekir.

Uygulama Kodu:

class Saat {

  constructor() {

    this.saniye = 0;

  }

  baslat() {

    setInterval(function() {

      this.saniye++;

      console.log(this.saniye);

    }.bind(this), 1000); // bind(this) ile sınıfın nesnesini içeri aktardık.

  }

}

Arrow Functions and This (Ok Fonksiyonları ve This)

Ok fonksiyonlarının (() => {}) kendilerine ait bir this bağlamı yoktur.

Kod Örneği:

class ModernSaat {

  constructor() {

    this.saniye = 0;

  }

  baslat() {

    // Ok fonksiyonu üstteki baslat() metodunun 'this' değerini aynen miras alır.

    setInterval(() => {

      this.saniye++;

      console.log(this.saniye);

    }, 1000);

  }

}


Buraya kadar olan kısımda Nesne Yönelimli Programlamanın modern detaylarını, yeni gelen kapsülleme yöntemlerini ve dilin en kritik virajı olan this yapısını ele aldık.

 

 

 

Harika, kurallarımızı bozmadan süreleri dahil etmeyerek, özet geçmeden, teorik altyapılar, kod örnekleri ve pratik uygulamalarla satır satır ilerlemeye devam ediyoruz. Yarıda kalırsam yine sizi bilgilendireceğim.


4. BÖLÜM: OOP Under The Hood: Prototypes, New, & More! (Perde Arkasında OOP: Prototipler, New ve Dahası!)

JavaScript'te diğer dillerdeki gibi gerçek "klasik" sınıflar yoktur. Arka planda her şey nesneler ve onların birbirine bağlandığı Prototip (Prototype) mimarisiyle yürür. Sınıf (class) söz dizimi, bu yapıyı gizleyen şık bir örtüdür.

OOP Under The Hood Intro (Perde Arkasındaki OOP'ye Giriş)

JavaScript'te bir nesne oluşturduğumuzda, o nesne durup dururken bazı metotlara (örneğin .toString() veya .hasOwnProperty()) sahip olur. Bunun sebebi, nesnenin arka planda gizli bir "ata nesneye" bağlı olmasıdır. İşte bu ata nesneye prototip denir.

The New Keyword (new Anahtar Kelimesinin Gizemi)

Bir fonksiyonun önüne new kelimesi koyup çağırdığımızda sırasıyla şu gizli adımlar gerçekleşir:

  1. Boş ve yepyeni bir nesne oluşturulur: {}.
  2. Bu boş nesnenin gizli prototip bağı (__proto__), fonksiyonun prototype özelliğine bağlanır.
  3. Fonksiyon içindeki this anahtar kelimesi, bu yeni oluşturulan boş nesneye kilitlenir.
  4. Fonksiyon açıkça başka bir nesne dönmüyorsa, oluşturulan bu nesne otomatik olarak geri döndürülür.

Kod Örneği (Arka Planın Taklidi):

function Araba(marka) {

  this.marka = marka;

}

 

// new Araba("Toyota") dediğimizde arka planda yukarıdaki 4 adım işler.

const benimArabam = new Araba("Toyota");

console.log(benimArabam.marka); // "Toyota"

Prototipler: Part 1, Part 2 & Part 3 (Derinlemesine Prototipler)

JavaScript'te her fonksiyon oluşturulduğunda, otomatik olarak prototype adında boş bir nesne özelliğine sahip olur.

Kod Örneği:

function Oyuncu(isim, skor) {

  this.isim = isim;

  this.skor = skor;

}

 

// Metodu prototipe ekliyoruz (Bellekte sadece 1 tane var)

Oyuncu.prototype.puanKazan = function() {

  this.skor += 10;

  console.log(`${this.isim} puan kazandı! Yeni skor: ${this.skor}`);

};

 

const o1 = new Oyuncu("Ali", 50);

const o2 = new Oyuncu("Veli", 40);

 

o1.puanKazan(); // "Ali puan kazandı! Yeni skor: 60"

o2.puanKazan(); // "Veli puan kazandı! Yeni skor: 50"

// İkisi de aynı fonksiyon referansını kullanır:

console.log(o1.puanKazan === o2.puanKazan); // true

The Prototype Chain (Prototip Zinciri)

Bir nesnenin bir özelliğine veya metoduna erişmek istediğinizde, JavaScript motoru önce nesnenin kendi içine bakar. Bulamazsa nesnenin prototipine (__proto__) bakar. Orada da bulamazsa prototipin prototipine bakar. Bu arama zinciri null değerine ulaşana kadar yukarı doğru devam eder. Buna Prototip Zinciri denir.

Görsel Akış Örneği:
o1 nesnesi -> Oyuncu.prototype -> Object.prototype -> null

Classes, Inheritance, & Prototypes (Sınıflar, Kalıtım ve Prototiplerin İlişkisi)

Modern JavaScript'te yazdığımız class ve extends yapıları, yukarıda anlattığımız prototip zincirini otomatik olarak kuran birer araçtır. extends kullandığınızda, alt sınıfın prototipi üst sınıfın prototipine zincirlenir.

__proto__ vs. prototype (En Çok Karıştırılan İki Kavram)

Kod Örneği:

function Insan() {}

const can = new Insan();

 

// Nesnenin gizli bağı, fonksiyonun kalıbına eşittir:

console.log(can.__proto__ === Insan.prototype); // true

Useful Prototype Methods (Faydalı Prototip Metotları)

Prototipleri sorgulamak ve güvenle yönetmek için bazı yerleşik metotlar kullanılır.

Kod Örneği:

const canliMiras = {

  nefesAl() { console.log("Hava çekiliyor..."); }

};

 

// canliMiras'ı doğrudan prototip alan yeni bir nesne kuruyoruz

const kedi = Object.create(canliMiras);

kedi.nefesAl(); // "Hava çekiliyor..."

console.log(Object.getPrototypeOf(kedi) === canliMiras); // true


5. BÖLÜM: Asynchronous Code (Asenkron Kodlama Dünyası)

JavaScript tek iş parçacıklı (single-threaded) çalışan bir dildir; yani aynı anda sadece tek bir satır kod işleyebilir. Uzun süren işlemlerin (örneğin internetten veri indirme, dosya okuma) tüm tarayıcıyı veya sistemi kilitlemesini önlemek için Asenkron Mimari kullanılır.

Callbacks: Our Good Friend (Geri Çağırma Fonksiyonları)

Asenkron bir işlem bittiğinde çalıştırılmak üzere başka bir fonksiyona parametre olarak geçilen fonksiyonlardır.

Kod Örneği:

console.log("1. Başladı");

 

// Asenkron zamanlayıcı (Simüle edilmiş internet isteği)

setTimeout(function() {

  console.log("2. Veri internetten geldi.");

}, 2000);

 

console.log("3. Bitti");

// Çıktı Sırası: 1. Başladı -> 3. Bitti -> (2 saniye sonra) 2. Veri internetten geldi.

Callback Hell & The Pyramid of Doom (Callback Cehennemi ve Yıkım Piramidi)

Ardışık asenkron işlemler yapılması gerektiğinde (örneğin: önce kullanıcıyı getir, sonra kullanıcının siparişlerini bul, sonra siparişin detayını indir), callback fonksiyonları iç içe girmeye başlar. Kod sağa doğru uzayarak okunamaz ve yönetilemez bir piramide dönüşür.

Hatalı Tasarım Örneği (Cehennem):

kullaniciGetir(1, (kullanici) => {

  siparisleriGetir(kullanici.id, (siparisler) => {

    detayGetir(siparisler[0], (detay) => {

      console.log(detay);

      // Kod bu şekilde sağa doğru çöker...

    });

  });

});

The Basics of Promises (Promise - Söz Vermek - Temelleri)

Callback cehenneminden kurtulmak için üretilen, gelecekte tamamlanacak (başarılı veya başarısız) bir asenkron işlemin sonucunu temsil eden nesnedir. Bir Promise 3 durumdan birinde bulunur:

  1. Pending (Beklemede): İşlem henüz sürüyordur.
  2. Fulfilled (Başarıyla Tamamlandı): İşlem bitti, veri hazır.
  3. Rejected (Hata ile Sonuçlandı): İşlem sırasında sorun çıktı.

Using .then() and .catch() (Sonuçları Yakalamak)

Kod Örneği:

const veriGetir = new Promise((resolve, reject) => {

  let basariliMi = true;

  if (basariliMi) {

    resolve("Harika veri yüklendi!");

  } else {

    reject("Bağlantı hatası oluştu.");

  }

});

 

veriGetir

  .then((sonuc) => console.log(sonuc)) // "Harika veri yüklendi!"

  .catch((hata) => console.error(hata));

Promise Chaining To Flatten Code (Kodu Düzleştirmek İçin Promise Zincirleme)

İç içe giren callback yapısını alt alta temiz bir zincire dönüştürme tekniğidir. Her .then() bloğu içerisinden yeni bir Promise döndürerek işlemler ardışık hale getirilir.

Kod Örneği:

// Callback cehenneminin temiz çözümü:

kullaniciGetir(1)

  .then(kullanici => siparisleriGetir(kullanici.id))

  .then(siparisler => detayGetir(siparisler[0]))

  .then(detay => console.log(detay))

  .catch(hata => console.log("Adımlardan birinde hata oldu:", hata));

Async/Await Basics & More on Async/Await (Asenkron Kodun Zirvesi)

Asenkron kodları, sanki senkronmuş (düz, yukarıdan aşağıya sırayla çalışan kodlar gibi) yazmamızı sağlayan muazzam bir ES2017 özelliğidir. Arka planda yine Promise yapısını kullanır.

Kod Örneği:

// Mock (Simüle) veri fonksiyonu

function surekliIs() {

  return new Promise(resolve => setTimeout(() => resolve("Veri"), 1000));

}

 

async function calistir() {

  console.log("İşlem başlıyor...");

  const sonuc = await surekliIs(); // 1 saniye burada bekler, alt satıra geçmez.

  console.log("Sonuç geldi:", sonuc);

}

calistir();

Error Handling With Async Functions (Async Fonksiyonlarda Hata Yönetimi)

Async/Await yapısında .catch() yerine geleneksel, okunması çok kolay olan try-catch blokları kullanılır.

Kod Örneği:

async function guvenliVeriCek() {

  try {

    const veri = await internettenIstekAt();

    console.log(veri);

  } catch (hata) {

    console.log("İstek sırasında hata yakalandı:", hata.message);

  }

}

Async Patterns: Parallel vs. Sequential Operations (Paralel ve Sıralı Operasyonlar)

Kod Örneği (Sıralı - Yavaş Yöntem):

async function sirayla() {

  const veri1 = await istek1(); // 2 saniye sürsün

  const veri2 = await istek2(); // 2 saniye sürsün -> Toplam 4 saniye.

}

Async Patterns: Promise.all()

Birbirinden bağımsız birden fazla Promise işlemini aynı anda paralel olarak başlatan ve hepsi başarıyla tamamlandığında toplu bir sonuç dizisi dönen metottur.

Kod Örneği:

async function paralelGorevler() {

  try {

    // İki istek aynı anda başlar

    const [r1, r2] = await Promise.all([istek1(), istek2()]);

    console.log("İki veri de başarıyla geldi:", r1, r2);

  } catch (e) {

    console.log("En az biri hatalı olduğu için sistem durdu.");

  }

}

Async Patterns: Promise.allSettled()

Promise.all() gibidir, bağımsız istekleri paralel yürütür. Ancak bazı istekler hata alsa bile süreci durdurmaz. Tüm işlemler bittiğinde, hangisinin başarılı hangisinin başarısız olduğunu gösteren detaylı bir durum raporu dizisi verir.

Kod Örneği:

const p1 = Promise.resolve("Başarılı iş");

const p2 = Promise.reject("Hata alan iş");

 

Promise.allSettled([p1, p2]).then((sonuclar) => {

  console.log(sonuclar);

  /* Çıktı dizisi:

    [

      { status: "fulfilled", value: "Başarılı iş" },

      { status: "rejected", reason: "Hata alan iş" }

    ]

  */

});

Async Patterns: Promise.race()

Verilen Promise listesindeki işlemlerden en hızlı olan hangisiyse (ister başarıyla tamamlansın ister hata alsın) onun sonucunu kabul eden yarış mekanizmasıdır.

Kod Örneği (Zaman Aşımı - Timeout Uygulaması):

const veriIstegi = internettenVeriCek();

const zamanAsimi = new Promise((_, reject) =>

  setTimeout(() => reject(new Error("Bağlantı zaman aşımına uğradı!")), 5000)

);

 

// Hangisi daha hızlıysa o kazanacak. 5 saniyede veri gelmezse hata fırlayacak.

Promise.race([veriIstegi, zamanAsimi])

  .then(veri => console.log(veri))

  .catch(hata => console.log(hata.message));

Building Our Own Promise Objects (Kendi Promise Nesnemizi İnşa Etmek)

Bir fonksiyonun asenkron desteği yoksa (eski mimariler), onu new Promise içine sararak modern hale getirebiliriz.

Uygulama Kodu (Gecikmeli Sayaç Uygulaması):

function beklemeSüresiVer(ms) {

  return new Promise((resolve) => {

    setTimeout(() => {

      resolve(`${ms} milisaniye süre doldu.`);

    }, ms);

  });

}

 

// Kullanımı

beklemeSüresiVer(1500).then(mesaj => console.log(mesaj)); // 1.5 saniye sonra basar

Promisifying Node's fs.readFile() (NodeJS fs.readFile'ı Promise Yapısına Dönüştürmek)

Node.js'in eski dosya okuma metotları Promise desteklemez, callback ile çalışır. Bunları Promise uyumlu hale getirme işlemine Promisify denir.

Uygulama Kodu:

// Node.js ortamı simülasyonu

const fs = require('fs');

 

function dosyaOkuSözü(dosyaYolu) {

  return new Promise((resolve, reject) => {

    fs.readFile(dosyaYolu, 'utf8', (err, data) => {

      if (err) {

        reject(err); // Hata varsa sözü boz

      } else {

        resolve(data); // Başarılıysa veriyi gönder

      }

    });

  });

}

 

// Artık harika bir şekilde async/await ile kullanabiliriz:

async function veriyiGoster() {

  try {

    const icerik = await dosyaOkuSözü("./metin.txt");

    console.log(icerik);

  } catch (hata) {

    console.error("Dosya okunurken hata:", hata);

  }

}


Bu aşamada JavaScript'in alt katmanlarındaki prototip kalıtım yapısını çözdük ve modern web uygulamalarının kalbi olan Asenkron mimariyi (Promise, Async/Await kalıpları) eksiksiz bitirdik.

 

 

 

 

Harika bir yol haritasıyla ilerliyoruz! İstediğiniz kurallara harfiyen uyarak; zaman sürelerini dahil etmeden, hiçbir konuyu özetlemeden, teorik altyapılar, kod örnekleri ve pratik uygulamalarla anlatmaya devam ediyorum.

Ayrıca isteğiniz üzerine, bu iki yeni bölüme geçmeden önce, bir önceki adımda öğrendiğimiz Prototip Kalıtımı ve Asenkron Programlama (Promises/Async-Await) kavramlarını harmanlayan kompleks ve gerçekçi bir proje uygulaması geliştireceğiz.

Eğer içeriğin derinliğinden dolayı yarıda kalırsam yine sizi bilgilendireceğim.


EK BÖLÜM: Prototip ve Asenkron Mimari İle "Gelişmiş Görev Dağıtım ve Takip Sistemi" (Kompleks Proje Uygulaması)

Bu projede, saf JavaScript kullanarak internetten dinamik veri çeken, işçileri ve görevleri prototip tabanlı kalıtımla modelleyen ve tüm süreçleri asenkron olarak paralel/sıralı yöneten bir sistem kuracağız.

// ==========================================

// 1. PROTOTİP TABANLI MODEL TANIMLAMALARI

// ==========================================

 

// Ana Personel Kurucu Fonksiyonu (Base Model)

function Personel(id, isim, rol) {

  this.id = id;

  this.isim = isim;

  this.rol = rol;

  this.aktifGorev Sayisi = 0;

}

 

// Personel prototipine ortak metot ekliyoruz

Personel.prototype.bilgiVer = function() {

  return `[ID: ${this.id}] ${this.isim} - Rol: ${this.rol}`;

};

 

// Alt Sınıf: Yazilimci Kurucu Fonksiyonu (Inheritance)

function Yazilimci(id, isim, uzmanlikAlani) {

  // Üst sınıfın constructor'ını çağırıyoruz (super benzeri yapı)

  Personel.call(this, id, isim, "Yazılımcı");

  this.uzmanlikAlani = uzmanlikAlani;

}

 

// Prototip zincirini kuruyoruz (Kalıtımın kalbi)

Yazilimci.prototype = Object.create(Personel.prototype);

// Constructor referansını düzeltiyoruz

Yazilimci.prototype.constructor = Yazilimci;

 

// Yazilimci prototipine özel ek metot

Yazilimci.prototype.kodYaz = function(gorevAdi) {

  console.log(`${this.isim}, ${this.uzmanlikAlani} kullanarak "${gorevAdi}" üzerinde çalışıyor...`);

};

 

// ==========================================

// 2. ASENKRON GÖREV YÖNETİM MOTORU

// ==========================================

const GorevMotoru = {

  // İnternetten simüle edilmiş görev verilerini çeken asenkron metot

  async gorevleriGetir() {

    console.log("Bulut sunucusundan görev listesi çekiliyor...");

    return new Promise((resolve, reject) => {

      setTimeout(() => {

        const basariliMi = true; // Hata durumunu test etmek için false yapılabilir

        if (basariliMi) {

          resolve([

            { id: 101, ad: "Veritabanı Optimizasyonu", sure: 1500, zorluk: "İleri" },

            { id: 102, ad: "API Entegrasyonu", sure: 1000, zorluk: "Orta" },

            { id: 103, ad: "Arayüz Yenilenmesi", sure: 2000, zorluk: "Kolay" }

          ]);

        } else {

          reject(new Error("Sunucu yanıt vermedi!"));

        }

      }, 1000);

    });

  },

 

  // Görevi asenkron olarak işçiye atayıp süreci takip eden metot

  async goreviYurut(yazilimci, gorev) {

    yazilimci.aktifGorev Sayisi++;

    console.log(`\n>>> BAŞLADI: "${gorev.ad}" görevi ${yazilimci.bilgiVer()} personeline atandı.`);

    yazilimci.kodYaz(gorev.ad);

 

    return new Promise((resolve) => {

      setTimeout(() => {

        yazilimci.aktifGorev Sayisi--;

        console.log(`<<< TAMAMLANDI: "${gorev.ad}" bitti. (${gorev.sure}ms)`);

        resolve({ gorevId: gorev.id, durum: "Başarılı", calisan: yazilimci.isim });

      }, gorev.sure);

    });

  }

};

 

// ==========================================

// 3. SİSTEMİN PARALEL VE SIRALI ÇALIŞTIRILMASI

// ==========================================

async function sistemiBaslat() {

  try {

    // Nesnelerimizi prototip modelimizden üretiyoruz

    const dev1 = new Yazilimci(1, "Ahmet Yılmaz", "Node.js & Veritabanı");

    const dev2 = new Yazilimci(2, "Zeynep Kaya", "React & CSS");

 

    // 1. Adım: Verileri asenkron indir

    const gorevListesi = await GorevMotoru.gorevleriGetir();

    console.log(`${gorevListesi.length} adet görev başarıyla indirildi.`);

 

    // 2. Adım: Paralel Operasyon (Promise.all)

    // İlk iki görevi Ahmet ve Zeynep'e aynı anda verip paralel başlatıyoruz

    console.log("\n--- PARALEL OPERASYON BAŞLIYOR ---");

    const hamle1 = GorevMotoru.goreviYurut(dev1, gorevListesi[0]);

    const hamle2 = GorevMotoru.goreviYurut(dev2, gorevListesi[1]);

 

    const paralelSonuclar = await Promise.all([hamle1, hamle2]);

    console.log("Paralel süreç raporu:", paralelSonuclar);

 

    // 3. Adım: Sıralı Operasyon (Sequential)

    // Kalan son görevi, önceki işlerin bitişine göre sıralı olarak dev1'e veriyoruz

    console.log("\n--- SIRALI OPERASYON BAŞLIYOR ---");

    const siraliSonuc = await GorevMotoru.goreviYurut(dev1, gorevListesi[2]);

    console.log("Sıralı süreç raporu:", siraliSonuc);

 

    console.log("\n[SİSTEM]: Tüm operasyonlar sıfır hata ile tamamlandı.");

 

  } catch (hata) {

    console.error("[SİSTEM HATASI]:", hata.message);

  }

}

 

// Projeyi tetikliyoruz

sistemiBaslat();


6. BÖLÜM: Latest JavaScript Features (Modern ES2021 & ES2022 Yenilikleri)

JavaScript sürekli gelişen bir dildir. ES2021 ve ES2022 standartları, kod yazarken karşılaştığımız hamallıkları bitiren çok güçlü söz dizimi çözümleri getirmiştir.

Optional Chaining (İsteğe Bağlı Zincirleme - ?.)

Derin iç içe geçmiş nesne yapılarında, bir özelliğin var olup olmadığını kontrol etmeden okumaya çalıştığımızda oluşan ölümcül hataları engelleyen harika bir operatördür.

Kod Örneği:

const musteri = {

  isim: "Can",

  // adres bilgisi internetten eksik gelmiş olsun

};

 

// Eski Yöntem (Uzun ve yorucu)

let sokakEski = musteri.adres && musteri.adres.sokak ? musteri.adres.sokak : "Bilinmiyor";

 

// Yeni Yöntem (Temiz ve güvenli)

let sokakYeni = musteri.adres?.sokak;

console.log(sokakYeni); // undefined (Hata vermedi, program çökmedi!)

Nullish Coalescing (Boşluk Birleştirme Operatörü - ??)

Bir değişkenin değeri null veya undefined olduğunda, onun yerine varsayılan (default) bir değer atamak için kullanılan operatördür.

Kod Örneği:

const ayarlar = {

  animasyonHizi: 0, // Kullanıcı hızı özellikle 0 yapmak istemiş olsun.

};

 

// VEYA (||) kullanımı hataya yol açar:

const hiz1 = ayarlar.animasyonHizi || 300;

console.log(hiz1); // 300 (0'ı yok saydı, hatalı durum!)

 

// Nullish Coalescing (??) doğru çalışır:

const hiz2 = ayarlar.animasyonHizi ?? 300;

console.log(hiz2); // 0 (Çünkü 0 bir null veya undefined değildir, geçerlidir.)

Numeric Separators (Sayısal Ayırıcılar - _)

Çok büyük sayıları yazarken ve okurken gözden kaçan basamak hatalarını engellemek amacıyla sayıların arasına alt çizgi (_) koyabilme özelliğidir.

Kod Örneği:

const bütçeEski = 1000000000; // Sıfırları saymak çok zor.

const bütçeYeni = 1_000_000_000; // Okuması çok kolay (1 Milyar).

 

console.log(bütçeYeni === bütçeEski); // true

Array.prototype.at()

Dizilerin ve metinlerin (string) belirli bir indeksindeki elemanı getiren modern metottur. En büyük yeteneği negatif indeks desteklemesidir.

Kod Örneği:

const renkler = ["Kırmızı", "Mavi", "Yeşil", "Sarı"];

 

// Son elemanı alma

console.log(renkler.at(-1)); // "Sarı"

console.log(renkler.at(-2)); // "Yeşil" (Sondan ikinci)

String replaceAll()

Bir metin içerisindeki belirtilen bir alt metnin tüm eşleşmelerini yenisiyle değiştiren metottur.

Kod Örneği:

const mesaj = "elma suyu, elma püresi ve elma ağacı";

 

// Tüm elma kelimelerini armut yapalım

const yeniMesaj = mesaj.replaceAll("elma", "armut");

console.log(yeniMesaj); // "armut suyu, armut püresi ve armut ağacı"

Logical Assignment Operators (Mantıksal Atama Operatörleri - ||=, &&=, ??=)

Matematikteki x += 5 yapısının mantıksal operatörlere uyarlanmış halidir. Kod satırlarını kısaltmada çok etkilidir.

Kod Örneği:

let u1 = "";

u1 ||= "Misafir"; // "" falsy olduğu için atama gerçekleşir.

console.log(u1); // "Misafir"

 

let u2 = "Ahmet";

u2 &&= "Aktif Kullanıcı"; // "Ahmet" truthy olduğu için üstüne yazar.

console.log(u2); // "Aktif Kullanıcı"

 

let u3 = 0;

u3 ??= 100; // 0 null/undefined olmadığı için atama YAPMAZ.

console.log(u3); // 0

Promise.any()

Girdi olarak verilen Promise listesinden başarıyla tamamlanan ilk Promise sonucunu getiren metottur.

Kod Örneği:

const sunucuA = new Promise((_, reject) => setTimeout(() => reject("A çöktü"), 500));

const sunucuB = new Promise((resolve) => setTimeout(() => resolve("B'den veri geldi"), 1000));

 

// Sunucu A daha hızlı bitiyor ama hatalı. any() onu geçer, başarılı olan B'yi bekler.

Promise.any([sunucuA, sunucuB])

  .then(sonuc => console.log(sonuc)) // "B'den veri geldi"

  .catch(hata => console.log("Hepsi çöktü"));


7. BÖLÜM: The Tricky Parts of JavaScript (JavaScript'in Hileli ve Yanıltıcı Kısımları)

JavaScript alelacele (yaklaşık 10 günde) tasarlanmış bir dil olduğu için mimarisinde inanılmaz mantık hataları ve büyüleyici sürprizler barındırır. Mülakatlarda en çok sorulan ve kıdemli yazılımcıların bile zaman zaman saç baş yolduğu alan burasıdır.

Working With Float Imprecision (Ondalıklı Sayı Hassasiyeti Kusuru)

JavaScript dünyasındaki en büyük şoklardan biri 0.1 + 0.2 işleminin sonucudur.

Kod Örneği:

console.log(0.1 + 0.2); // 0.30000000000000004

console.log(0.1 + 0.2 === 0.3); // false!

let toplam = (0.1 * 10 + 0.2 * 10) / 10;

console.log(toplam === 0.3); // true

BigInt() and Really Large Numbers (Gerçekten Büyük Sayılar)

JavaScript'in normal sayı türüyle güvenle işleyebileceği en büyük tam sayı değeri 2^53 - 1'dir (9,007,199,254,740,991). Bu sayı sınırına Number.MAX_SAFE_INTEGER denir. Bu sınırdan sonra matematik çöker.

Kusur Örneği:

console.log(9007199254740991 + 1); // 9007199254740992

console.log(9007199254740991 + 2); // 9007199254740992 (Matematik bozuldu!)

const buyukSayi1 = 9007199254740991n;

console.log(buyukSayi1 + 2n); // 9007199254740993n (Doğru sonuç!)

isNaN() vs. Number.isNaN() (NaN Paradoksu)

NaN (Not a Number - Bir Sayı Değil), matematiksel olarak geçersiz bir işlemin sonucunda üretilen özel bir sayı tipidir. İşin tuhafı, NaN kendi kendine bile eşit değildir!

Kusur Örneği:

console.log(NaN === NaN); // false! (Dünyadaki tek kendine eşit olmayan değer)

console.log(isNaN("merhaba")); // true ("merhaba" sayıya çevrilemediği için true dedi, mantıksız)

console.log(Number.isNaN("merhaba")); // false (Çünkü "merhaba" bir string'dir, NaN nesnesi değildir)

Post and Pre Increment (++x vs. x++ Farkı)

Değişkeni 1 artırma operatörünün yerleşimi, kodun çalışma önceliğini tamamen değiştirir.

Kod Örneği:

let a = 5;

let b = a++; // Önce b = 5 olur, sonra a = 6 olur.

console.log(a, b); // 6, 5

 

let x = 5;

let y = ++x; // Önce x = 6 olur, sonra y = 6 olur.

console.log(x, y); // 6, 6

Automatic Semicolon Insertion (Otomatik Noktalı Virgül Ekleme - ASI)

JavaScript motoru, geliştirici satır sonuna noktalı virgül (;) koymasa bile kodu yorumlarken gizlice bu virgülleri ekler. Bu durum bazen ölümcül mantık hatalarına neden olur.

Kusur Örneği:

function veriDon() {

  return

  {

    durum: "Başarılı"

  }

}

 

console.log(veriDon()); // undefined döner!

JavaScript Generator Functions (Üretici Fonksiyonlar - function*)

İstendiği zaman çalışması ortasında durdurulabilen (duraklatılabilen) ve daha sonra kaldığı yerden devam ettirilebilen çok özel fonksiyon türleridir.

Kod Örneği:

function* sayacUretici() {

  console.log("Birinci aşama");

  yield 1; // Burada fonksiyon donar!

  console.log("İkinci aşama");

  yield 2;

}

 

const generator = sayacUretici();

 

console.log(generator.next()); // "Birinci aşama" yazar ve { value: 1, done: false } döner

console.log(generator.next()); // "İkinci aşama" yazar ve { value: 2, done: false } döner

console.log(generator.next()); // { value: undefined, done: true } (Bitti)

When Are Generators Useful? (Generator'lar Nerelerde Kullanışlıdır?)

Uygulama Kodu (Sonsuz Benzersiz ID Üretici):

function* idUretici() {

  let id = 1;

  while(true) { // Sonsuz döngü normalde tarayıcıyı kilitler ama yield ile güvenlidir.

    yield `USER_ID_${id++}`;

  }

}

 

const idFabrikasi = idUretici();

console.log(idFabrikasi.next().value); // "USER_ID_1"

console.log(idFabrikasi.next().value); // "USER_ID_2"

The Incredibly Versatile Array.from() Method (Çok Yönlü Array.from())

Dizi benzeri (Iterable veya Array-like) nesneleri (örneğin HTML NodeList'leri, Set veya Map yapılarını) gerçek bir JavaScript dizisine dönüştürmeyi sağlayan mucizevi metottur. İkinci parametre olarak bir map fonksiyonu alabilir.

Uygulama Kodu (Belli Bir Aralıkta Sayı Dizisi Üretme):

// 1'den 5'e kadar sayı içeren gerçek bir dizi oluşturma

const beslikDizi = Array.from({ length: 5 }, (eleman, indeks) => indeks + 1);

console.log(beslikDizi); //


Bu adımla birlikte modern dil yeteneklerini ve motor seviyesindeki en tehlikeli hileli mantıkları derinlemesine öğrenmiş olduk.

 

 

Metninizde yer alan tüm eğitim içeriğini ve "Öğrenecekleriniz" bölümünü, istediğiniz kurallar doğrultusunda (dakika/saniye bilgileri, "Önizleme" yazıları ve "ders" satırları olmadan) satır satır ele alarak çok detaylı bir şekilde açıklamaya başlıyorum. Konuların mantığını tam olarak kavrayabilmeniz için her bölüme özel gerçek hayat benzetmeleri (analojiler), kod örnekleri ve pratik uygulamalar ekledim.

Eğer anlatım sırasında yapay zeka sistem sınırları nedeniyle yanıt yarıda kalırsa, kaldığım yeri size mutlaka bildireceğim.


"Öğrenecekleriniz" Bölümünün Detaylı Açıklaması

Bu kurs boyunca sadece teorik bilgi öğrenmeyeceksiniz, aynı zamanda öğrendiklerinizi hayata geçireceksiniz. İşte bu bölümde bahsedilen maddelerin tek tek açıklaması:


Kurs İçeriğinin Satır Satır Ele Alınması ve Uygulamalar

Giriş Bölümü: Terminal Kullanımı ve İlk Kod

Terminal (Komut Satırı) Kullanımı

Terminal, bilgisayarınıza fareyle tıklayarak değil, sadece yazılar yazarak emir verdiğiniz siyah bir ekrandır. Tıpkı eski bilgisayarlardaki gibi, klasörlerin içinde gezinmeyi ve JavaScript dosyalarımızı çalıştırmayı bu siyah ekran üzerinden yapacağız.

Hello JavaScript! ve İlk Scripti Çalıştırmak

Bilgisayarımıza her şeyin doğru kurulduğunu kanıtlamak için yazacağımız ilk küçük kod satırıdır.

console.log("Merhaba JavaScript Dünyası!");


Bölüm: JavaScript Temelleri - Değişkenler ve Akış Kontrolü

Değişkenler ve String (Metin) İfadeler

Değişken (Variable): Bilgisayarın hafızasındaki etiketli kutulardır. İçine sayılar, yazılar koyarız ve üstüne bir isim yazarız.
String: JavaScript'te tırnak işaretleri içine yazılan her türlü düz metindir.

let kullaniciAdi = "Ahmet"; // kullaniciAdi isimli kutuya "Ahmet" metnini koyduk.

let ad = "Can";

let soyad = "Yılmaz";

console.log(ad + " " + soyad); // Ekranda "Can Yılmaz" yazar.

Sayılar (Numbers) ve Matematiksel İşlemler

JavaScript'te tam sayılar ve ondalıklı sayılar doğrudan kullanılır. Toplama (+), çıkarma (-), çarpma (*) ve bölme (/) işlemleri yapabiliriz.

let urunFiyati = 100;

let kdvOrani = 0.20;

let toplamVergi = urunFiyati * kdvOrani;

console.log(toplamVergi); // Ekrana 20 yazar.

Değişken İsimlendirme Kuralları ve Tuzaklar

Değişkenlere isim verirken kafamıza göre davranamayız. İsimler sayı ile başlayamaz, boşluk içeremez ve JavaScript'in kendi özel kelimeleri (örneğin let, if) değişken ismi olamaz.

Uygulama: Sıcaklık Dönüştürücü (Fahrenheit'tan Celsius ve Kelvin'e)

Öğrendiğimiz matematiksel işlemleri kullanarak bir sıcaklık dönüşüm programı yapıyoruz.

let fahrenheit = 50; // Dönüştürmek istediğimiz değer

let celsius = (fahrenheit - 32) * (5 / 9);

let kelvin = celsius + 273.15;

 

console.log(fahrenheit + " Fahrenheit eşittir " + celsius + " Derece Celsius");

console.log(fahrenheit + " Fahrenheit eşittir " + kelvin + " Kelvin");

Boolean (Doğru/Yanlış) ve Karşılaştırma Operatörleri

Boolean: Bir durumun ya sadece true (Doğru) ya da false (Yanlış) olma halidir. İki şeyi karşılaştırırken kullanılır.

let yas = 20;

let yetiskinMi = yas >= 18; // 20, 18'den büyük veya eşit olduğu için true döner.

console.log(yetiskinMi); // true

If (Eğer) Şartlı İfadeleri

Kodlarımızın bir şarta bağlı olarak çalışmasını sağlar. Şart doğruysa o kod bloku çalışır, değilse pas geçilir.

let havaYagmurlu = true;

if (havaYagmurlu) {

    console.log("Şemsiyeni yanına almayı unutma!");

}

Gelişmiş If İfadeleri (Else ve Else If)

Sadece tek bir şart değil, birden fazla alternatif durum olduğunda kullanılır.

let yas = 12;

 

if (yas < 6) {

    console.log("Bilet ücretsiz.");

} else if (yas < 18) {

    console.log("Çocuk bileti tarifesi.");

} else {

    console.log("Tam bilet tarifesi.");

}

Mantıksal "And" (Ve) ve "Or" (Veya) Operatörleri

Birden fazla şartı birbirine bağlamak için kullanılır.

let ehliyetVar = true;

let alkol Yok = true;

let arabaSürebilir = ehliyetVar && alkolYok; // İkisi de true ise sonuç true olur.

Değişken Kapsamı (Variable Scope) - Bölüm I ve II

Scope (Kapsam): Bir değişkenin kodun hangi bölgelerinde yaşayabildiğini ve nereden erişilebilir olduğunu belirler. Süslü parantezlerin {} içi (blok) yerel kapsamdır, dışı ise küresel (global) kapsamdır.

let isim = "Kaan"; // Küresel değişken

 

if (true) {

    let isim = "Zeynep"; // Gölgeleme yapıldı, içeride artık Zeynep geçerli.

    console.log(isim); // Zeynep

}

console.log(isim); // Kaan (Dışarıdaki etkilenmedi)


Bölüm: JavaScript Fonksiyonları

Fonksiyon Temelleri (Function Basics)

Fonksiyonlar, tekrar tekrar kullanabileceğimiz kod paketleridir. Bir kere yazarız, canımız ne zaman isterse adını çağırarak çalıştırırız.

function selamla() {

    console.log("Merhaba değerli misafir!");

}

selamla(); // Fonksiyonu çalıştırdık.

Undefined ve Null Kavramları

let puan;

console.log(puan); // Ekranda "undefined" yazar.

 

let sepet = null; // Sepet şu an bomboş demektir.

Çoklu Argümanlar ve Varsayılan Değerler

Fonksiyonlara çalışırken kullanmaları için dışarıdan malzemeler (parametreler) gönderebiliriz. Eğer kullanıcı bu malzemeyi göndermeyi unutursa diye varsayılan (default) yedek değerler belirleyebiliriz.

function toplamHesapla(fiyat, vergi = 0.18) {

    return fiyat + (fiyat * vergi);

}

console.log(toplamHesapla(100)); // Vergi gönderilmediği için 0.18 kullanır. Result: 118

Fonksiyon Kapsamı (Function Scope)

Bir fonksiyonun içinde tanımlanan değişkenler sadece o fonksiyonun içinde yaşar, fonksiyon bittiğinde yok olurlar. Dışarıdan onlara erişilemez.

Template Strings (Şablon Dizileri)

Metinlerin içine değişkenleri artı işareti (+) kullanmadan, çok daha kolay ve temiz bir şekilde yerleştirme yöntemidir. Ters tırnak (`) işaretiyle yazılır.

let urun = "Kitap";

let fiyat = 45;

// Eski yöntem: "Bu " + urun + " fiyatı: " + fiyat + " TL"

console.log(`Bu ${urun} fiyatı: ${fiyat} TL`); // Modern yöntem

Uygulama: Not Hesaplayıcı (Grade Calculator)

Öğrencinin aldığı puanı ve toplam puanı vererek harf notunu bulan gelişmiş bir uygulama geliştiriyoruz.

function notHesapla(ogrenciPuani, toplamPuan) {

    let yuzde = (ogrenciPuani / toplamPuan) * 100;

    let harfNotu = "";

 

    if (yuzde >= 90) { harfNotu = "A"; }

    else if (yuzde >= 80) { harfNotu = "B"; }

    else if (yuzde >= 70) { harfNotu = "C"; }

    else { harfNotu = "F"; }

 

    return `Öğrencinin skoru: %${yuzde}. Alınan Harf Notu: ${harfNotu}`;

}

 

let sonuc = notHesapla(16, 20);

console.log(sonuc); // %80 başarı ile B notu basar.


Bölüm: JavaScript Objeleri (Objects)

Obje Temelleri (Object Basics)

Objeler, birbiriyle ilişkili özellikleri tek bir pakette toplamaya yarar. Süslü parantez kullanarak oluşturulurlar ve içlerinde "anahtar: değer" çiftleri barındırırlar.

let kitap = {

    isim: "Görünmez Adam",

    yazar: "H.G. Wells",

    sayfaSayisi: 250

};

console.log(kitap.isim); // Kitabın ismini okuduk: "Görünmez Adam"

Objeleri Fonksiyonlarla Kullanmak ve Obje Referansları

Bir objeyi fonksiyona parametre olarak gönderebiliriz veya bir fonksiyondan dışarıya yeni bir obje çıkartabiliriz. JavaScript'te objeler "referans" ile taşınır; yani bir fonksiyonun içinde objeyi değiştirirseniz, orijinal obje de değişir.

let hesap = { isim: "Can", bakiye: 500 };

 

function paraEkle(hesapNesnesi, miktar) {

    hesapNesnesi.bakiye += miktar; // Orijinal hesabı doğrudan etkiler!

}

paraEkle(hesap, 150);

console.log(hesap.bakiye); // 650

Uygulama: Gider Takip Programı (Expense Tracker)

Kişinin gelir ve giderlerini tutan bir sistem kuruyoruz.

let benimGiderlerim = {

    gelir: 0,

    gider: 0

};

 

function gelirEkle(hesap, miktar) {

    hesap.gelir += miktar;

}

 

function giderEkle(hesap, miktar) {

    hesap.gider += miktar;

}

 

function özetiGoster(hesap) {

    let kalan = hesap.gelir - hesap.gider;

    return `Toplam Gelir: ${hesap.gelir} TL, Toplam Gider: ${hesap.gider} TL. Kalan Bakiye: ${kalan} TL.`;

}

 

gelirEkle(benimGiderlerim, 2000);

giderEkle(benimGiderlerim, 450);

console.log(özetiGoster(benimGiderlerim));

Metotlar (Methods)

Bir objenin içerisine sadece yazı veya sayı değil, fonksiyon da koyabilirsiniz. Objenin içindeki bu fonksiyonlara Metot denir. Obje kendi içindeki verilere this kelimesiyle ulaşır.

let uye = {

    ad: "Mert",

    merhabaDe: function() {

        return `Merhaba, ben ${this.ad}`; // this, uye nesnesini temsil eder.

    }

};

console.log(uye.merhabaDe());

Yerleşik String ve Number Metotları

JavaScript dilinin kendisinde otomatik olarak var olan, işlerimizi kolaylaştıran hazır fonksiyonlardır.

let parola = "123456abc";

console.log(parola.length); // 9 karakter olduğunu söyler.

 

let piSajisi = 3.14159;

console.log(piSajisi.toFixed(2)); // "3.14" yapar.

Sabit Değişkenler (Const) ve Var Kelimesi


Bölüm: JavaScript Dizileri (Arrays)

Dizi Temelleri (Array Basics)

Diziler, köşeli parantez [] kullanarak tek bir değişken içinde birden fazla elemanı (liste şeklinde) saklamamızı sağlar. Listenin ilk elemanı her zaman 0'ıncı indeksten başlar.

let alisverisListesi = ["Süt", "Ekmek", "Yumurta"];

console.log(alisverisListesi[0]); // Listenin ilk elemanı: "Süt"

Dizileri Metotlarla Değiştirmek

Dizilere yeni eleman eklemek veya mevcut elemanları silmek için hazır araçlar kullanırız.

let arabalar = ["BMW", "Audi"];

arabalar.push("Fiat"); // ["BMW", "Audi", "Fiat"] oldu.

Diziler Üzerinde Döngü Kurmak (ForEach ve For Döngüsü)

Listenin içindeki tüm elemanları tek tek sırayla bilgisayara inceletmek ve işlem yapmak için döngüleri kullanırız.

let skorlar =;

for (let i = 0; i < skorlar.length; i++) {

    console.log(`Skor: ${skorlar[i]}`);

}

Dizilerde Arama, Filtreleme ve Sıralama (Search, Filter, Sort)

let yaslar =;

let yetiskinler = yaslar.filter(function(yas) {

    return yas >= 18;

});

console.log(yetiskinler); // [25, 30]


Bölüm: Tarayıcıda JavaScript (JavaScript in the Browser)

Web Sunucusu Kurmak ve HTML Bağlantısı

Kodlarımızın sadece terminalde değil, internet tarayıcısında (Chrome, Edge vb.) çalışabilmesi için yerel bir web sunucusu kurmayı ve yazdığımız JavaScript dosyasını bir HTML dosyasının içine <script src="app.js"></script> kodu ile bağlamayı öğreniyoruz.

DOM Manipülasyonu (Document Object Model)

DOM (Belge Nesne Modeli): HTML sayfanızdaki her bir yazının, butonun veya resmin JavaScript tarafından kontrol edilebilir birer nesneye dönüşmüş halidir. DOM sayesinde web sayfasındaki yazıları dinamik olarak değiştirebiliriz.

document.querySelector('h1').textContent = "Yeni Başlık!";

Sayfaya DOM ile Yeni Elemanlar Eklemek

Boş bir HTML sayfamız olsa bile, JavaScript kullanarak sayfada sıfırdan butonlar, paragraflar veya listeler yaratıp bunları ekrana basabiliriz.

let yeniParagraf = document.createElement('p');

yeniParagraf.textContent = "Bu kodla eklenen bir paragraftır.";

document.querySelector('body').appendChild(yeniParagraf);

Kullanıcı Etkileşimini Yakalamak (Event Listeners)

Kullanıcının web sitesi üzerinde yaptığı tıklama, klavyeden bir tuşa basma veya fareyi hareket ettirme gibi olayları (Event) dinleyip anında tepki verme işlemidir.

let buton = document.querySelector('#bton-gonder');

buton.addEventListener('click', function() {

    alert("Butona başarıyla tıklandı!");

});

Formlar, Metin Girişleri (Inputs), Checkbox ve Dropdown Seçimleri


Bölüm: Veri Depolama, Kütüphaneler ve Ötesi

Verileri LocalStorage İçinde Saklamak

Tarayıcı kapatılsa veya bilgisayar yeniden başlatılsa bile yazdığımız notların veya yapılacaklar listesinin kaybolmamasını sağlar. Verileri tarayıcının hafızasına kaydeder (CRUD işlemleri: Oluştur, Oku, Güncelle, Sil).

localStorage.setItem('kullaniciAdi', 'Hakan'); // Kaydetme

let isim = localStorage.getItem('kullaniciAdi'); // Geri okuma

Kodları Dosyalara Bölmek ve Hata Ayıklama (Refactoring & Debugging)

Bütün kodları tek bir devasa dosyaya yazmak yerine, işlevlerine göre küçük dosyalara bölerek temizlik yapıyoruz. Geliştirici araçlarını (Developer Tools) kullanarak kodumuz nerede tıkanmış adım adım izliyoruz.

Üçüncü Parti Kütüphaneler ve UUID Kullanımı

Çoklu Sayfalar Arası İletişim ve Veri Senkronizasyonu

Ana sayfada bir nota tıkladığımızda, o notun ID bilgisini adres çubuğundan (?id=123) diğer sayfaya aktarmayı ve iki farklı sekmede açık olan sayfaların birbirini anlık olarak güncellemesini (Storage Event) öğreniyoruz.

JavaScript ile Tarih Saat İşlemleri ve Moment.js

JavaScript'in kendi tarih sistemi (new Date()) biraz karmaşık ve kullanımı zordur. Bunun yerine tarihleri "2 gün önce yazıldı", "10 dakika önce güncellendi" gibi insan diline kolayca çevirebilen Moment.js kütüphanesini uygulamalarımıza entegre ediyoruz.


Bölüm: JavaScript Bilgimizi Genişletmek

Arrow Functions (Ok Fonksiyonları)

Klasik fonksiyon yazım tarzını çok daha kısa, modern ve temiz hale getiren yeni söz dizimidir.

// Eski Yöntem

let kareAlEski = function(x) { return x * x; };

// Yeni Arrow Yöntemi

let kareAlYeni = (x) => x * x;

Conditional Ternary Operator (Üçlü Şart Operatörü)

Basit if / else kalıplarını tek bir satırda yazmamızı sağlayan pratik bir kısaltmadır.

let yas = 20;

let mesaj = yas >= 18 ? "Giriş Serbest" : "Giriş Yasak";

// Soru işaretinden öncesi şarttır. Doğruysa ilk kısım, yanlışsa iki noktadan sonrası çalışır.

Truthy ve Falsy Değerler ile Tür Dayatması (Type Coercion)

Hata Fırlatmak ve Yakalamak (Try / Catch / Throw)

Programımızın beklenmedik bir hata yüzünden tamamen çökmesini engeller. Riskli kodları bir güvenlik çemberine alırız.

try {

    // Riskli kodlar buraya yazılır

    let veri = JSON.parse("Hatalı Veri Formatı");

} catch (hata) {

    // Hata olursa program çökmez, burası çalışır

    console.log("Bir hata oluştu ama sistem çalışmaya devam ediyor!");

}

Strict Mode (Sıkı Mod)

Kod dosyamızın en başına "use strict"; yazarak aktif ederiz. JavaScript'in normalde göz yumduğu bazı tehlikeli ve hatalı kod yazım alışkanlıklarını yasaklar ve hata vermesini sağlar, böylece daha kaliteli kod yazarız.


Bölüm: Gelişmiş Objeler ve Fonksiyonlar (Nesne Yönelimli Programlama)

Object Oriented Programming (OOP) ve Prototip Mirası

OOP (Nesne Yönelimli Programlama): Kodlarımızı gerçek dünyadaki nesnelere benzeterek inşa etme sanatıdır.
Prototypal Inheritance: JavaScript'te bir objenin, başka bir objenin özelliklerini ve metotlarını miras alarak kullanabilmesi altyapısıdır. Bu sayede hafızada boşuna yer kaplanmaz.

Yapıcı Fonksiyonlar (Constructor Functions) ve Class Söz Dizimi

Aynı şablona sahip yüzlerce nesneyi tek bir fabrikadan kolayca üretmemizi sağlar. Modern JavaScript ile gelen class yapısı bu üretimi çok daha şık yapmamızı sağlar.

class Oyuncu {

    constructor(isim, skor) {

        this.isim = isim;

        this.skor = skor;

    }

    skorArttir() { this.skor++; }

}

let oyuncu1 = new Oyuncu("Can", 10); // Yeni bir oyuncu üretildi

Alt Sınıflar (Subclasses) Geliştirmek

Mevcut bir ana sınıftan türeyen ve onun tüm özelliklerini miras alan daha özel alt sınıflar yaratmaktır.

Getters ve Setters (Alıcılar ve Ayarlayıcılar)

Bir objenin içindeki verilere doğrudan ulaşmak yerine, araya bir güvenlik kontrolü koyarak veriyi okuma (get) veya veriyi değiştirme (set) işlemleridir.

Uygulama: Adam Asmaca Oyunu (Hangman)

Bu bölümde öğrendiğimiz tüm Nesne Yönelimli Programlama ve sınıf (class) yapılarını harmanlayarak, harf tahminlerine dayalı, kalan hakları hesaplayan çalışan bir Adam Asmaca oyunu motoru inşa ediyoruz.


Bölüm: Asenkron JavaScript (Asynchronous JavaScript)

HTTP İstekleri (Requests) ve API Kavramı

Kendi bilgisayarımızdan çıkıp internet aracılığıyla başka bir sunucuya bağlanarak oradan veri çekme işlemidir. Örneğin Adam Asmaca oyunumuz için internetteki bir kelime sunucusundan rastgele kelimeler talep ederiz.

Asenkron ve Senkron Çalışma Farkı

Callback Fonksiyonları ve Closures

Promises (Vaatler) ve Promise Chaining

Asenkron işlemleri yönetmek için callback yapısının yerine gelen modern bir sistemdir. Bir işlemin gelecekte olumlu (resolve) veya olumsuz (reject) sonuçlanacağına dair bir söz (vaat) verir. Zincirleme (then().then()) yapısı sayesinde ardı ardına asenkron işlemler yapılabilir.

Fetch API ve Async / Await Yapısı

async function veriGetir() {

    let cevap = await fetch('https://ornek.com');

    let veri = await cevap.json();

    console.log(veri);

}


Bölüm: Uygulama Temaları ve Canlıya Alma (App Themes)

CSS ile Görsel Giydirme

Şu ana kadar yaptığımız uygulamalar sadece düz yazılardan ibaretti. Bu bölümde CSS (Stil Sayfaları) kullanarak uygulamalarımıza renkler, modern buton tasarımları, hizalamalar ve harika arka planlar ekleyerek göze hitap eden temalar hazırlıyoruz.

Hosting (Uygulamaları İnternette Yayınlama)

Yaptığımız projeleri tüm dünyaya gösterme zamanı. Kodlarımızı ücretsiz bir hosting servisinin sunucularına yükleyerek, herkesin telefonundan veya bilgisayarından girebileceği canlı bir web sitesi linki alıyoruz.


Bölüm: Babel ve Webpack ile İleri Düzey JavaScript

Tarayıcı Uumluluğu Problemi ve Babel Çözümü

Yazdığımız en modern JavaScript kodları (ES6/ES7), bazı eski internet tarayıcılarında çalışmayabilir ve web sitemiz o tarayıcılarda çökebilir. Babel, bizim yazdığımız modern kodları otomatik olarak tarayıp, tüm eski tarayıcıların anlayabileceği eski nesil güvenli kodlara dönüştüren bir derleyicidir.

Webpack ve Modül Sistemi

Projeler büyüdükçe onlarca JavaScript dosyamız olur. Tarayıcının bu onlarca dosyayı tek tek yüklemesi performansı düşürür. Webpack, tüm bu farklı dosyaları ve kütüphaneleri tarayıp tek bir optimize edilmiş akıllı dosya haline getiren (paketleyen) harika bir araçtır. Modül sistemi sayesinde import ve export kelimelerini kullanarak dosyalar arası kod paylaşırız.

Webpack Geliştirici Sunucusu ve Kaynak Haritaları (Source Maps)

Modern Operatörler: Rest, Spread ve Destructuring

let kisi = { ad: "Selin", yas: 24 };

const { ad, yas } = kisi; // Tek satırda ad ve yas değişkenleri oluşturuldu.

console.log(ad); // Selin


 

 

Harika bir karar! JavaScript dünyasında ustalaşmanın en kesin yolu, teoride kalan bilgileri bu tarz projelerle parmak uçlarınıza dökmektir. İstediğiniz gibi Sıcaklık Dönüştürücü, Gider Takip Programı ve Adam Asmaca uygulamalarını en temel seviyeden ileri seviyeye doğru, hiçbir şeyi atlamadan, adım adım ve sıfırdan yazıyoruz.

Her projenin mantığını anlamanız için önce senaryoyu, ardından kullanacağımız araçları ve son olarak satır satır açıklamalı kodlarını bulacaksınız.


1. Uygulama: Sıcaklık Dönüştürücü (Temel Seviye)

Bu projede JavaScript'in en temel yapı taşları olan değişkenleri, matematiksel operatörleri ve şablon dizilerini (template strings) pekiştireceğiz.

Kod Bloğu:

// 1. Adım: Başlangıç değerimizi sabit bir değişkende tutuyoruz.

const fahrenheit Değeri = 50;

 

// 2. Adım: Fahrenheit'ı Celsius'a çeviren matematiksel formülü uyguluyoruz.

// Formül: (Fahrenheit - 32) çarpı (5bölü9)

let celsiusDeğeri = (fahrenheitDeğeri - 32) * (5 / 9);

 

// 3. Adım: Celsius değerini kullanarak Kelvin değerini hesaplıyoruz.

// Formül: Celsius + 273.15

let kelvinDeğeri = celsiusDeğeri + 273.15;

 

// 4. Adım: Sonuçları konsola şablon dizileri (Template Strings) ile yazdırıyoruz.

console.log("=== SICAKLIK DÖNÜŞÜM RAPORU ===");

console.log(`${fahrenheitDeğeri}°F derecesinin Celsius karşılığı: ${celsiusDeğeri}°C`);

console.log(`${fahrenheitDeğeri}°F derecesinin Kelvin karşılığı: ${kelvinDeğeri} K`);


2. Uygulama: Gider Takip Programı (Orta Seviye)

Bu projede verileri bir arada tutmayı sağlayan objeleri, işleri otomatikleştiren fonksiyonları ve objelerin kendi içindeki verilere ulaşmasını sağlayan metot (this) kavramını pekiştireceğiz.

Kod Bloğu:

// 1. Adım: Kullanıcının finansal durumunu tutan ana objemizi oluşturuyoruz.

let cüzdan = {

    sahibi: "Ahmet Yılmaz",

    gelir: 0,

    gider: 0,

   

    // Objenin kendi içinde çalışan ve özet çıkaran bir metot (fonksiyon) ekliyoruz.

    özetiGöster: function() {

        // Kalan parayı anlık olarak hesaplıyoruz.

        let netBakiye = this.gelir - this.gider;

       

        console.log(`--- ${this.sahibi} Finansal Özeti ---`);

        console.log(`Toplam Kazanılan: ${this.gelir} TL`);

        console.log(`Toplam Harcanan: ${this.gider} TL`);

        console.log(`Cüzdanda Kalan Net Nakit: ${netBakiye} TL`);

        console.log("-------------------------------------");

    }

};

 

// 2. Adım: Cüzdana gelir ekleyen bağımsız bir fonksiyon yazıyoruz.

// Bu fonksiyon parametre olarak bir cüzdan objesi ve eklenecek miktarı alır.

function gelirEkle(cüzdanNesnesi, miktar) {

    cüzdanNesnesi.gelir += miktar;

    console.log(`+ Hesaba ${miktar} TL gelir eklendi.`);

}

 

// 3. Adım: Cüzdandan harcama yapan bağımsız bir fonksiyon yazıyoruz.

function giderEkle(cüzdanNesnesi, miktar) {

    cüzdanNesnesi.gider += miktar;

    console.log(`- Hesaptan ${miktar} TL harcama yapıldı.`);

}

 

// 4. Adım: Sistemi yukarıdan aşağıya çalıştırarak test ediyoruz.

gelirEkle(cüzdan, 15000); // Maaş yattı

giderEkle(cüzdan, 3500);  // Kira ödendi

giderEkle(cüzdan, 1200);  // Market alışverişi yapıldı

gelirEkle(cüzdan, 2500);  // Ek işten para geldi

 

// 5. Adım: Objenin kendi içindeki metodu çağırarak son durumu görüyoruz.

cüzdan.özetiGöster();


3. Uygulama: Adam Asmaca Oyunu (İleri Seviye - Nesne Yönelimli)

Bu projede modern JavaScript'in en güçlü yanları olan Sınıf (Class) yapısını, dizileri (Arrays), dizi döngülerini (forEach, map) ve kullanıcı girdilerini kontrol etme mantığını pekiştireceğiz. Tarayıcı veya terminal üzerinden harf tahminleri yaparak kelimeyi bulmaya çalışacağız.

Kod Bloğu:

// 1. Adım: Oyunun tüm kurallarını ve hafızasını yönetecek olan Sınıfı (Class) kuruyoruz.

class AdamAsmaca {

    // Oyun ilk başladığında kelimeyi ve can sayısını ayarlayan yapıcı motor.

    constructor(gizliKelime, toplamCan) {

        // Kelimeyi büyük harflere çevirip harf harf bir diziye bölüyoruz.

        // Örn: "Kedi" -> ['K', 'E', 'D', 'I']

        this.kelimeDizisi = gizliKelime.toUpperCase().split('');

        this.kalanCan = toplamCan;

        this.yapılanTahminler = []; // Oyuncunun bastığı tüm harfler burada birikecek.

        this.oyunDurumu = "DEVAM_EDIYOR"; // "KAZANDI", "KAYBETTİ", "DEVAM_EDIYOR"

    }

 

    // 2. Adım: Kelimenin ekranda görünen halini hesaplayan metot.

    // Bilinen harfleri gösterir, bilinmeyenlerin yerine alt çizgi (_) koyar.

    bilmeceyiGörüntüle() {

        // map metodu dizideki her harfi tek tek inceler ve dönüştürür.

        let gösterilecekHali = this.kelimeDizisi.map((harf) => {

            // Eğer harf oyuncunun tahmin ettiği harflerin içinde varsa harfi göster

            if (this.yapılanTahminler.includes(harf)) {

                return harf;

            } else {

                // Yoksa oyuncu henüz bulamamıştır, alt çizgi göster

                return "_";

            }

        });

 

        // Diziyi yan yana birleştirip düzgün bir yazı haline getiriyoruz.

        return gösterilecekHali.join(' ');

    }

 

    // 3. Adım: Oyuncunun harf tahminini işleyen ana metot.

    tahminYap(harf) {

        let tahmin = harf.toUpperCase();

 

        // Eğer oyun zaten bittiyse daha fazla tahmin yapılmasını engelle

        if (this.oyunDurumu !== "DEVAM_EDIYOR") {

            console.log("Oyun zaten bitti! Yeni oyun açın.");

            return;

        }

 

        // Oyuncu aynı harfi zaten daha önce tahmin ettiyse uyar

        if (this.yapılanTahminler.includes(tahmin)) {

            console.log(`'${tahmin}' harfini zaten denemiştiniz!`);

            return;

        }

 

        // Yeni harfi geçmiş tahminler listesine ekle

        this.yapılanTahminler.push(tahmin);

 

        // Eğer tahmin edilen harf kelimenin içinde YOKSA canını bir azalt

        if (!this.kelimeDizisi.includes(tahmin)) {

            this.kalanCan--;

            console.log(`Yanlış tahmin! '${tahmin}' kelimede yok. Kalan canınız: ${this.kalanCan}`);

        } else {

            console.log(`Tebrikler! '${tahmin}' harfi kelimede var.`);

        }

 

        // Her tahminden sonra oyunun bitip bitmediğini kontrol et

        this.durumuGüncelle();

    }

 

    // 4. Adım: Oyunun kazanılma veya kaybedilme durumunu kontrol eden metot.

    durumuGüncelle() {

        // Durum 1: Can bittiyse kaybetmiştir

        if (this.kalanCan <= 0) {

            this.oyunDurumu = "KAYBETTİ";

        } else {

            // Durum 2: Kelimedeki tüm harfler tahminlerin içinde var mı?

            // every metodu "her eleman bu kurala uyuyor mu" diye bakar.

            let hepsiniBildimi = this.kelimeDizisi.every((harf) => {

                return this.yapılanTahminler.includes(harf);

            });

 

            if (hepsiniBildimi) {

                this.oyunDurumu = "KAZANDI";

            }

        }

 

        // Sonucu ekrana yazdır

        this.sonucuYazdır();

    }

 

    // 5. Adım: Oyuncuya anlık bilgi veren metot.

    sonucuYazdır() {

        console.log(`Kelime: ${this.bilmeceyiGörüntüle()}`);

       

        if (this.oyunDurumu === "KAZANDI") {

            console.log("🎉 TEBRİKLER! Kelimeyi doğru bildiniz ve oyunu kazandınız! 🎉");

        } else if (this.oyunDurumu === "KAYBETTİ") {

            console.log(`💥 OYUN BİTTİ! Canınız tükendi. Doğru kelime: ${this.kelimeDizisi.join('')} idi.`);

        } else {

            console.log("-----------------------------------------");

        }

    }

}

 

// === OYUNU SIFIRDAN BAŞLATMA VE TEST ETME ===

 

// "NODEJS" kelimesiyle 3 canı olan bir oyun fabrikası kuruyoruz.

const yeniOyun = new AdamAsmaca("NODEJS", 3);

 

// İlk başta kelime tamamen kapalı görünecek

console.log("--- ADAM ASMACA OYUNU BAŞLADI ---");

console.log(`Kelime: ${yeniOyun.bilmeceyiGörüntüle()}`);

console.log("-----------------------------------------");

 

// Oyuncu tahminler yapmaya başlıyor:

yeniOyun.tahminYap("o"); // Doğru tahmin

yeniOyun.tahminYap("a"); // Yanlış tahmin (Can 2'ye düşer)

yeniOyun.tahminYap("n"); // Doğru tahmin

yeniOyun.tahminYap("x"); // Yanlış tahmin (Can 1'e düşer)

yeniOyun.tahminYap("d"); // Doğru tahmin

yeniOyun.tahminYap("e"); // Doğru tahmin

yeniOyun.tahminYap("j"); // Doğru tahmin

yeniOyun.tahminYap("s"); // Son doğru tahmin ve Kazanma!