Menu

TypeScript Erişim Belirleyiciler: public, private, protected

TypeScript'te üç erişim belirleyici vardır: public, private ve protected, bunlara ek olarak readonly. Her birinin neye izin verdiğini, TypeScript'teki private'ın neden bir derleme zamanı kontrolü olduğunu, JavaScript #private alanlarının ise çalışma zamanında nasıl korunduğunu ve hangisini seçeceğinizi öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

TypeScript'te sınıf üyeleri için üç erişim belirleyici vardır: public (varsayılan), protected ve private. Bir üyenin nerede kullanılabileceğini belirlerler ve derleyici yanlış yerden yapılan her erişimi bildirir.

Son satır bir derleme hatasıdır, ama yine de çalıştırıldığında ne yazdırdığına bakın: 123-45-6789. Bu sayfadaki en önemli bilgi budur ve private bölümü bunu açıklıyor.

Her Belirleyici Neye İzin Verir

BelirleyiciSınıfın içindeAlt sınıftaDışarıdanÇalışma zamanında korunur
public (varsayılan)evetevetevetkorunacak bir şey yok
protectedevetevethayırhayır
privateevethayırhayırhayır
#name (JavaScript)evethayırhayırevet
readonlyokuma, constructor içinde yazmaokumaokumahayır

Belirleyiciler alanlarda, metotlarda, getter ve setter'larda, constructor'larda ve parametre özelliklerinde (constructor(private id: string)) çalışır. public yazmak isteğe bağlıdır ve birçok kod tabanı onu hiç yazmaz.

private Bir Derleme Zamanı Kontrolüdür

TypeScript, private belirleyicisini diğer tiplerle birlikte siler. Derlenmiş sınıfta sıradan bir özellik vardır; bu yüzden tip denetleyicisinden geçmeyen her şey onu görür: düz JavaScript çağıranları, JSON.stringify, Object.keys ve hatta bilinçli bir kaçış yolu olarak izin verilen TypeScript'in kendi köşeli parantez gösterimi.

Bu, private belirleyicisinin asıl amacı için sorun değildir: diğer geliştiricilere (ve editörünüze) bir üyenin bir implementasyon ayrıntısı olduğunu söylemek. Bir güvenlik sınırı değildir ve siz kendiniz çıkarmadıkça private bir alan loglara ve JSON yanıtlarına girer.

#private Alanlar: Çalışma Zamanında Korunur

JavaScript'in # ile yazılan kendi private alanları vardır. Bunları motor korur: sınıfın dışında obj.#field geçerli bir sözdizimi bile değildir ve alan Object.keys, JSON.stringify ya da console.log çıktısında görünmez.

Sınıfın dışında s.#token yazmak TS18013 hatasıdır (Property '#token' is not accessible outside class 'Session' because it has a private identifier) ve private durumundan farklı olarak çalışma zamanında da bunun bir yolu yoktur. Çalışma zamanı kuralları için JavaScript'te private alanlar sayfasına bakın.

private mı #private mı: Hangisini Kullanmalı

private x#x
Kontrol edenderleyiciJavaScript motoru
Object.keys / JSON.stringify görür müevethayır
Köşeli parantezle erişim obj["x"]izinlimümkün değil
Alt sınıf kendi x alanını bildirebilir mihayır, çakışırevet, her sınıfın kendi #x alanı vardır
Spread { ...obj } ile kopyalanır mıevethayır
Metotlardaki sözdizimiprivate helper()#helper()

Verinin çalışma zamanında da gizli kalması gerekiyorsa (token'lar, bir kütüphanenin kullanıcılarının dokunmaması gereken iç durum) ya da JSON.stringify çıktısında yer almasını istemiyorsanız #private kullanın. Amaç yalnızca temiz bir public API ise, bir framework'ün alanı reflection ile okuması gerekiyorsa ya da kod tabanının mevcut stiline uymak istiyorsanız private kullanın. İkisini birleştirmeyin: private #x, TS18010 hatasıdır (An accessibility modifier cannot be used with a private identifier).

protected ve Alt Sınıflar

protected bir üye sınıfın içinde ve onu genişleten her sınıfta kullanılabilir, ancak dışarıdan örnekler üzerinden kullanılamaz.

Bir kural insanları şaşırtır. Polygon içinde sides alanını this üzerinde ya da başka bir Polygon üzerinde okuyabilirsiniz, ama parametre olarak geçirilen düz bir Shape üzerinde okuyamazsınız: other: Shape iken other.sides, TS2446 hatasıdır (Property 'sides' is protected and only accessible through an instance of class 'Polygon'. This is an instance of class 'Shape'.). Bir alt sınıf yalnızca hiyerarşide kendi dalına ait nesnelerin protected üyelerine ulaşabilir.

Bir alt sınıf, protected bir üyeyi yeniden bildirerek public yapabilir, ama public bir üyeyi protected ya da private yapamaz. Üyeyi bir başlangıç değeriyle (public override sides = 6) ya da yalnızca tip olarak (declare public sides: number) yeniden bildirin. Tek başına public sides: number; yazmak TS2564 ve TS2612 ile reddedilir, çünkü modern sınıf alanlarında bu, super() döndükten sonra miras alınan değeri undefined olarak sıfırlardı.

readonly

readonly, oluşturma işleminden sonra yeniden atamayı engeller. Alan bildiriminde ya da constructor içinde ayarlanabilir; sonraki her atama TS2540 hatasıdır.

Burada iki sınır ortaya çıkıyor. readonly yüzeyseldir: dizi başka bir diziyle değiştirilemez ama içeriği değişebilir (push işlemini engellemek için tipini readonly string[] yapın). Ve private gibi çalışma zamanında kaybolur, bu yüzden derleyicinin reddettiği atama yine de çalıştı. Çalışma zamanında değişmemesi gereken bir değer için Object.freeze ya da setter'ı olmayan bir getter kullanın. readonly sayfası Readonly<T> ve readonly dizileri anlatıyor.

readonly erişim belirleyicilerle birlikte kullanılabilir: private readonly cache = new Map<string, number>(), dahili olan ve hiç yeniden atanmayan bir alan için yaygın bir kalıptır.

Sık Yapılan Hatalar

  • private belirleyicisini güvenlik sanmak. Çalışma zamanında yoktur. Gizli kalması gereken veriler için #field kullanın ve gizli bilgiler içeren bir nesneyi asla doğrudan JSON.stringify içine vermeyin.
  • Her yere public yazmak. Zaten varsayılandır; eklemek hiçbir şeyi değiştirmez.
  • "Dahili" olan her şey için protected kullanmak. Hiçbir alt sınıf ona ihtiyaç duymuyorsa private dışa açık yüzeyi daha küçük tutar.
  • readonly belirleyicisinin iç içe veriyi dondurmasını beklemek. Yalnızca özelliğin kendisinin yeniden atanmasını durdurur.

Sıkça Sorulan Sorular

TypeScript'te erişim belirleyiciler nelerdir?

public (varsayılan: her yerden erişilebilir), protected (sınıfın ve alt sınıflarının içinden) ve private (yalnızca sınıfın içinden). readonly ise constructor'dan sonra yeniden atamayı engelleyen ayrı bir belirleyicidir ve üçünden herhangi biriyle birlikte kullanılabilir.

TypeScript'te private ile #private arasındaki fark nedir?

private yalnızca derleyici tarafından kontrol edilir; üretilen JavaScript'te sıradan bir özellik vardır, bu yüzden obj["secret"], JSON.stringify ve Object.keys onu yine görür. #secret ise bir JavaScript private alanıdır: onu çalışma zamanı korur ve sınıfın dışındaki kod onu hiçbir şekilde okuyamaz.

TypeScript'teki private gerçekten private mıdır?

Yalnızca derleme zamanında. Derlemeden sonra alan, her JavaScript kodunun okuyabileceği normal bir özelliktir. TypeScript, bir kaçış yolu olarak private üyelere köşeli parantezle erişime (obj["field"]) bile izin verir. Gizliliğin çalışma zamanında da korunması gerekiyorsa #field kullanın.

TypeScript'te protected ile private arasındaki fark nedir?

private bir üye yalnızca onu bildiren sınıfın içinde görünür. protected bir üye alt sınıfların içinde de görünür. İkisine de sınıf hiyerarşisinin dışından bir örnek üzerinden erişilemez.

TypeScript'te readonly özellikler değiştirilebilir mi?

readonly bir özellik bildiriminde ya da constructor içinde atanabilir, başka hiçbir yerde atanamaz (aksi halde TS2540). Yüzeyseldir: readonly tags: string[] başka bir diziyle değiştirilemez ama tags.push() yine çalışır. Bunu da engellemek için readonly string[] kullanın.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA