- Konu sahibi
- #1
JavaScript OOP, programı birlikte çalışan nesneler üzerinden tasarlama yaklaşımıdır. Nesneler verileri özelliklerde, bu verilerle ilgili davranışları ise metotlarda tutar. JavaScript özünde prototip tabanlıdır;
OOP özellikle bir uygulamada aynı türden birçok varlık bulunuyorsa yararlıdır. Örneğin kullanıcı, sepet, ürün veya ödeme gibi kavramların her biri kendi verisini ve bu veri üzerinde çalışan işlemleri taşıyabilir. Böylece tüm işlemleri tek bir uzun fonksiyon veya dağınık global değişkenler içinde tutmak yerine sorumlulukları ayırırsınız.
Sınıf: Benzer nesnelerin nasıl oluşturulacağını tanımlar. Sınıf doğrudan gerçek kullanıcı değildir; kullanıcı nesneleri üretmek için kullanılan bir şablondur.
Nesne: Sınıftan oluşturulan veya doğrudan nesne söz dizimiyle tanımlanan somut değerdir.
Özellik: Nesnenin tuttuğu veridir. Örneğin bir kullanıcının adı veya bakiyesi.
Metot: Nesnenin gerçekleştirdiği işlemdir. Örneğin para yatırma veya ürün ekleme.
Kapsülleme: Veriye doğrudan erişimi sınırlandırıp değişiklikleri kontrollü metotlar üzerinden yapmaktır. JavaScript'te sınıf alanlarının başına
Kalıtım: Bir sınıfın başka bir sınıfın davranışlarını genişletmesidir.
Çok biçimlilik: Farklı nesnelerin aynı metot adını kendi davranışlarına göre uygulayabilmesidir. Örneğin farklı bildirim türleri aynı
Aşağıdaki örnek, kullanıcı bakiyesini dışarıdan doğrudan değiştirilemeyecek şekilde tutar. Dosyayı
Çalıştırma adımı şöyledir:
Burada
JavaScript'te her veri için sınıf yazmak gerekmez. Basit ve tek kullanımlık bir veri grubu için nesne söz dizimi veya düz fonksiyonlar daha anlaşılır olabilir. Aynı kurallara sahip çok sayıda nesne, gizlenmesi gereken durum veya nesnenin davranışları varsa sınıf kullanmak mantıklıdır.
Kalıtımı varsayılan çözüm olarak kullanmayın. Bir nesne başka bir nesnenin gerçekten özel türüyse
Her şeyi sınıfa koymak: Küçük bir işlem için sınıf kullanmak kodu gereksiz büyütebilir.
Alanları herkese açık bırakmak: Değişmesi gereken değerleri doğrudan dışarı açmak, geçersiz durumların oluşmasına neden olabilir. Değişiklikleri doğrulayan metotlar kullanın.
Kalıtım zincirini büyütmek: Çok katmanlı sınıflarda davranışın nereden geldiğini izlemek zorlaşır. Önce kompozisyonu değerlendirin.
Metot çağrısında
class, constructor, extends ve super gibi yapılar bu model üzerinde daha okunabilir bir yazım biçimi sağlar.OOP özellikle bir uygulamada aynı türden birçok varlık bulunuyorsa yararlıdır. Örneğin kullanıcı, sepet, ürün veya ödeme gibi kavramların her biri kendi verisini ve bu veri üzerinde çalışan işlemleri taşıyabilir. Böylece tüm işlemleri tek bir uzun fonksiyon veya dağınık global değişkenler içinde tutmak yerine sorumlulukları ayırırsınız.
JavaScript'te OOP'nin temel parçaları
Sınıf: Benzer nesnelerin nasıl oluşturulacağını tanımlar. Sınıf doğrudan gerçek kullanıcı değildir; kullanıcı nesneleri üretmek için kullanılan bir şablondur.
Nesne: Sınıftan oluşturulan veya doğrudan nesne söz dizimiyle tanımlanan somut değerdir.
Özellik: Nesnenin tuttuğu veridir. Örneğin bir kullanıcının adı veya bakiyesi.
Metot: Nesnenin gerçekleştirdiği işlemdir. Örneğin para yatırma veya ürün ekleme.
Kapsülleme: Veriye doğrudan erişimi sınırlandırıp değişiklikleri kontrollü metotlar üzerinden yapmaktır. JavaScript'te sınıf alanlarının başına
# koyarak gerçek özel alan oluşturabilirsiniz.Kalıtım: Bir sınıfın başka bir sınıfın davranışlarını genişletmesidir.
extends ve super bunun için kullanılır. Ancak yalnızca ortak ve gerçekten anlamlı bir ilişki varsa tercih edilmelidir.Çok biçimlilik: Farklı nesnelerin aynı metot adını kendi davranışlarına göre uygulayabilmesidir. Örneğin farklı bildirim türleri aynı
gonder() metoduna sahip olabilir.| İhtiyaç | Uygun yaklaşım | Neden |
|---|---|---|
| Tek bir basit veri grubu | Nesne söz dizimi | Gereksiz yapı oluşturmaz |
| Aynı davranışa sahip çok sayıda varlık | class | Üretimi ve ortak metotları düzenler |
| Dışarıdan korunması gereken durum | Özel alan ve metot | Değişiklikleri kurallı hale getirir |
| Birden fazla bağımsız yeteneği birleştirme | Kompozisyon | Karmaşık kalıtım zincirlerini önler |
Çalışan bir OOP örneği
Aşağıdaki örnek, kullanıcı bakiyesini dışarıdan doğrudan değiştirilemeyecek şekilde tutar. Dosyayı
banka.js adıyla kaydedip Node.js ile çalıştırabilirsiniz.
JavaScript:
class BankaHesabi {
#bakiye = 0;
constructor(sahip) {
this.sahip = sahip;
}
paraYatir(tutar) {
if (!Number.isFinite(tutar) || tutar <= 0) {
throw new Error("Tutar sonlu ve sıfırdan büyük bir sayı olmalı.");
}
this.#bakiye += tutar;
}
bakiyeGoster() {
return this.#bakiye;
}
}
const hesap = new BankaHesabi("Ayşe");
hesap.paraYatir(500);
console.log(hesap.sahip);
console.log(hesap.bakiyeGoster());
Çalıştırma adımı şöyledir:
- Kodda
BankaHesabisınıfı bir hesap şablonu olarak tanımlanır. -
new BankaHesabi("Ayşe")ifadesi bu sınıftan bir nesne üretir. -
paraYatir(500)metodu bakiyeyi kontrollü biçimde değiştirir. - Dosyayı
node banka.jskomutuyla çalıştırın. Beklenen çıktı sırasıylaAyşeve500değerleridir. - Negatif, sıfır, NaN, sonsuz veya metin türünde tutar verirseniz hata alınır; bu, doğrulama koşulunun çalıştığını gösterir.
hesap.#bakiyeyazarsanız da alan özel olduğu için doğrudan okunamaz.
Burada
#bakiye yalnızca sınıfın içinden kullanılabilir. Dış kodun bakiyeyi istediği değere ayarlayamaması, nesnenin kendi kurallarını korumasını sağlar. Gerçek uygulamada para hesapları için kayan nokta hassasiyeti, para birimi ve işlem güvenilirliği gibi ek kurallar ayrıca tasarlanmalıdır; bu küçük örnek yalnızca OOP yapısını gösterir.Hangi yaklaşımı seçmelisiniz?
JavaScript'te her veri için sınıf yazmak gerekmez. Basit ve tek kullanımlık bir veri grubu için nesne söz dizimi veya düz fonksiyonlar daha anlaşılır olabilir. Aynı kurallara sahip çok sayıda nesne, gizlenmesi gereken durum veya nesnenin davranışları varsa sınıf kullanmak mantıklıdır.
Kalıtımı varsayılan çözüm olarak kullanmayın. Bir nesne başka bir nesnenin gerçekten özel türüyse
extends anlamlıdır; yalnızca kod tekrarını azaltmak için kullanılıyorsa ortak yardımcı fonksiyon veya kompozisyon daha kolay sürdürülebilir olabilir.Sık yapılan hatalar
Her şeyi sınıfa koymak: Küçük bir işlem için sınıf kullanmak kodu gereksiz büyütebilir.
Alanları herkese açık bırakmak: Değişmesi gereken değerleri doğrudan dışarı açmak, geçersiz durumların oluşmasına neden olabilir. Değişiklikleri doğrulayan metotlar kullanın.
Kalıtım zincirini büyütmek: Çok katmanlı sınıflarda davranışın nereden geldiğini izlemek zorlaşır. Önce kompozisyonu değerlendirin.
Metot çağrısında
this bağlamını unutmak: Bir metodu nesneden ayırıp geri çağrı olarak verirseniz this beklediğiniz nesneyi göstermeyebilir. Gerektiğinde bind, ok fonksiyonu veya uygun bir sarmalayıcı kullanın.