Konuya Genel Bakış
TypeScript'te özel alanlar başlangıçta private modifikatörü ile tanıtılmıştır, fakat ECMAScript 2021'den itibaren JavaScript'te gerçek özel alanlar # sembolü ile desteklenmektedir. Temel amaç, sınıfın iç detaylarını dışarıdan erişime karşı koruyarak veri kapsüllemektir.
Sorun
TypeScript'teki private modifikasyonu sadece derleme aşamasında özel alanların gizliliğini sağlar, ancak derlenmiş JavaScript'te bu alanlar nesne özelliklerine doğrudan erişim ile kullanılabilir. Bu, nesnenin durumunun kazara değiştirilmesine yol açabilir. ES Özel Alanları (#) ise, JavaScript çalıştırılma zamanında sınıf dışından tamamen ulaşılamaz, bu da verilerin gerçek anlamda korunmasını sağlar.
Çözüm
TypeScript her iki yaklaşımı da destekler. Aralarından seçim yaparken, koruma gereksinimlerinize ve JavaScript sürümleri ile uyumluluk kısıtlamalarınıza dikkat etmelisiniz.
Kod örneği:
class Example { private hidden: number; #trulyHidden: string; constructor() { this.hidden = 42; this.#trulyHidden = 'secret'; } getHidden() { return this.hidden; } getTrulyHidden() { return this.#trulyHidden; } } const x = new Example(); // x.hidden — TS'de hata, ama JS'de x['hidden'] üzerinden erişim mümkün // x.#trulyHidden — JS'de bile sözdizimsel hata
Ana özellikler:
private, sadece TypeScript derleme aşamasında gizliliği garanti eder#field, JavaScript çalıştırma zamanında gerçek gizliliği sağlar# kullanımı modern JS (ES2021+) desteği gerektirirTypeScript sınıfındaki özel bir alana doğrudan JS ile erişim mümkün müdür?
Evet, mümkündür çünkü gizlilik sadece derleme aşamasında sağlanır. Kaynak JS'de alan, sıradan bir nesne özelliği olacaktır. Örneğin:
class A { private x = 1; } const a = new A(); console.log((a as any)["x"]); // 1
Arayüzlerde veya tiplerde # ile tanımlanan özel alanlar kullanılabilir mi?
Hayır, #private alanları yalnızca sınıfın uygulaması ile ilgilidir ve arayüzlerde, tiplerde ya da sınıf dışındaki herhangi bir yerde tanımlanamaz. Arayüzler sadece kamu üyelerini tanımlar.
# ile tanımlanan özel alanlar miras alınabilir mi?
Hayır, bu alanlar miras alan sınıflara erişilemez. Sadece kendisi bu alanlara erişebilir:
class Parent { #foo = 123; } class Child extends Parent { // this.#foo = 444; // Hata }
private kullanımı — doğrudan erişimle zayıflığa yol açarParolaların saklandığı bir projede, User sınıfında private password alanı kullanılmıştır. Geliştiricilerden biri, hata ayıklama için user['password'] ile tesadüfen erişim sağlar ve bu alan dışardaki bir modül tarafından değiştirilir.
Artılar:
Eksiler:
Geliştirici ES özel alan #password kullanır. Artık alanlara indeksleme veya miras alma yoluyla erişim girişimleri başarısız olur, verilerin güvenliği üçüncü parti kütüphaneler ve araçlar kullanıldığında bile sağlanır.
Artılar:
Eksiler: