JavaScript: Başlangıçtan İleri Seviyeye
Bölüm 22 / 313 dk okuma

Sınıflar ve `this`

ES6 class sözdizimi, constructor, instance/static metotlar ve this'in inceliği.

JavaScript'te sınıflar, prototip-tabanlı sistemin üzerine yazılmış sözdizimi şekeridir. C#/Java'daki "class"tan farklı çalışırlar (sonraki bölümde detay).

Temel sınıf

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
 
  greet() {
    return `Merhaba, ben ${this.name}`;
  }
}
 
const u = new User("Furkan", 28);
u.greet();  // "Merhaba, ben Furkan"

Instance vs static

class MathUtils {
  // instance method
  square(n) { return n * n; }
 
  // static method — instance'a bağlı değil
  static circleArea(r) { return Math.PI * r * r; }
 
  // static property
  static PI = 3.14159;
}
 
MathUtils.circleArea(5);   // ✅ direkt sınıf üzerinden
MathUtils.PI;              // ✅
new MathUtils().square(5); // ✅ instance üzerinden

Getter / setter

class Temperature {
  constructor(celsius) {
    this._c = celsius;
  }
 
  get fahrenheit() {
    return this._c * 9 / 5 + 32;
  }
 
  set fahrenheit(f) {
    this._c = (f - 32) * 5 / 9;
  }
}
 
const t = new Temperature(20);
t.fahrenheit;     // 68
t.fahrenheit = 100;
t._c;             // ~37.78

Private fields (ES2022)

class Counter {
  #count = 0;
 
  increment() { this.#count++; }
  get value() { return this.#count; }
}
 
const c = new Counter();
c.increment();
c.value;     // 1
c.#count;    // ❌ SyntaxError

# prefix ile gerçekten private. Eski dönemde _underscore sadece konvansiyondu, dışarıdan erişilebilirdi.

Inheritance

class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} ses çıkardı`; }
}
 
class Dog extends Animal {
  constructor(name, breed) {
    super(name);    // parent constructor
    this.breed = breed;
  }
 
  speak() {
    return `${super.speak()} — Hav!`;
  }
}
 
new Dog("Karabaş", "Kangal").speak();
// "Karabaş ses çıkardı — Hav!"

super ile parent'in constructor/method'una erişirsin.

this — JavaScript'in en kafa karıştıran özelliği

this çağrım anına göre belirlenir, tanımlandığı yere göre değil.

4 farklı bağlam

function show() { return this; }
 
// 1. Yalın çağrı — strict mode'da undefined, normal mode'da global
show();
 
// 2. Method çağrısı — sahip olan obje
const obj = { show };
obj.show();   // obj
 
// 3. new ile — yeni instance
class Foo { constructor() { console.log(this); } }
new Foo();
 
// 4. .call/.apply/.bind — manuel binding
show.call({ x: 1 });   // { x: 1 }

Klasik bug: this kaybı

class Btn {
  constructor() {
    this.text = "Click";
    document.querySelector("button").addEventListener("click", this.onClick);
  }
 
  onClick() {
    console.log(this.text); // ❌ undefined — this artık button
  }
}

Çözümler:

// 1. Arrow function ile sınıf alanı (en temiz)
class Btn {
  text = "Click";
  onClick = () => {
    console.log(this.text);
  };
}
 
// 2. bind
this.onClick = this.onClick.bind(this);
 
// 3. Wrap içinde arrow
button.addEventListener("click", () => this.onClick());

Arrow function ve this

Arrow function kendi this'ini oluşturmaz. Tanımlandığı kapsamın this'ini kullanır:

class Timer {
  constructor() { this.count = 0; }
 
  start() {
    setInterval(() => {
      this.count++;       // ✅ Timer instance'ı
    }, 1000);
  }
}

Bu yüzden React'te ve callback'lerde arrow function tercih edilir.

💡Pratik

Class metodu olarak event handler yazıyorsan arrow function field kullan. bind kuralları unutuluyor, arrow zaten doğru this'i yakalar.

Bu bölümü bitirdin mi?

İlerlemen tarayıcıda saklanır, eğitim listesinde görünür.

Paylaş