JavaScript'te Sınıfların Ek Özellikleri
Bu makalede, JavaScript'te sınıfların ek özelliklerini açıklayacağız.
YouTube Video
JavaScript'te Sınıfların Ek Özellikleri
JavaScript'te Özel (Private) Özellikler
JavaScript'te, özel özellikler yalnızca nesne veya sınıf içinde erişilebilen özelliklerdir. Bu, kapsülleme sağlayarak harici kodların doğrudan değişiklik yapmasını veya erişmesini engelleyerek daha güvenli ve sağlam bir kod tasarımı sağlar.
2020 yılında ECMAScript 2020 (ES11) ile sınıf içinde özel alanlar tanımlamak için #
(diyez) kullanımı tanıtıldı. Bu, geleneksel JavaScript özel konvansiyonlarının yerine (örneğin, alt çizgiyle başlayan değişken adları) daha net bir yöntem sağlar.
Özel (Private) Özelliklerin Avantajları
Aşağıdakiler, özel özelliklerin avantajlarıdır.
- Kapsülleme: Dahili durumu dışarıdan gizler ve veri tutarlılığını sağlar.
- Güvenlik: Harici kod tarafından özelliklerin yanlışlıkla değiştirilmesini engeller.
- Geliştirilmiş Bakım Kolaylığı: Nesnelerin veya sınıfların uygulanmasını gizler ve dışarıya gösterilen arayüzü netleştirir.
Özel (Private) Özellikler Nasıl Kullanılır
Sınıflarda Özel (Private) Özelliklerin Tanımlanması
Özel alanlar, #
ile başlayan bir isim kullanılarak tanımlanır. Bu alana, sınıfın örneklerinden veya alt sınıflarından doğrudan erişilemez.
1class Person {
2 // Define private property
3 #name;
4
5 constructor(name) {
6 this.#name = name;
7 }
8
9 // Method to access the private property
10 getName() {
11 return this.#name;
12 }
13
14 // Method to change the private property
15 setName(newName) {
16 this.#name = newName;
17 }
18}
19
20const john = new Person("John");
21console.log(john.getName()); // John
22
23// Cannot access private property directly
24console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
Yukarıdaki kodda, #name
Person
sınıfının dışında doğrudan erişilemeyen bir özel özelliktir. İsme yalnızca getName
ve setName
yöntemleri üzerinden erişebilir veya değiştirebilirsiniz.
Özel (Private) Metotları Tanımlama
Özel özellikler gibi özel metotlar da #
ile başlayan bir isim kullanılarak tanımlanır. Özel metotlar yalnızca sınıfın içinden çağrılabilir.
1class Counter {
2 #count = 0;
3
4 increment() {
5 this.#count++;
6 this.#logCount(); // Calling private method
7 }
8
9 // Private method
10 #logCount() {
11 console.log(`Current count: ${this.#count}`);
12 }
13}
14
15const counter = new Counter();
16counter.increment(); // Current count: 1
17
18// Cannot access private method directly
19counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class
Burada, #logCount
bir özel metot olarak tanımlanmıştır ve sınıfın dışından erişilemez. Bu metot yalnızca sınıf içerisinde kullanılır.
Özel (Private) Özelliklerin Avantajları ve Dikkat Edilmesi Gerekenler
Avantaj
- Sınıfın dışından doğrudan erişilemediği için, istenmeyen değişiklikler veya işlemler engellenir.
- Dışarıdan görünmeyen bölümler iyi gizlenebileceği için, bir API olarak açığa çıkardığınız bölümleri net bir şekilde yönetebilirsiniz.
Notlar
- Özel alanlar sınıfın dışından tamamen gizlendiği için, test ve hata ayıklama zorlaşabilir. Bu nedenle, tasarım aşamasında kapsamlı bir şekilde test edilebilecek bir API sağlamak önemlidir.
- Özel alanlar, her örnek için benzersiz olduklarından, prototip tabanlı özelliklere sahip JavaScript'in diğer bölümlerinden farklı bir şekilde davranır.
Özel Özelliklerin Geleneksel Takma İsimle Uygulaması
#
kullanılarak özel alanlar tanıtılmadan önce, JavaScript'in özel özellikler için resmi bir sözdizimi yoktu. Bu nedenle, geçmişte takma özel özellikler şu şekilde uygulanıyordu.
Alt çizgi kullanma geleneği
Geliştiriciler, değişken adlarının başına alt çizgi ekleyerek 'özel' olduğunu geleneksel olarak belirtirlerdi.
1class Car {
2 constructor(brand) {
3 this._brand = brand; // Using an underscore to indicate private
4 }
5
6 getBrand() {
7 return this._brand;
8 }
9}
10
11const car = new Car("Toyota");
12console.log(car.getBrand()); // Toyota
13console.log(car._brand); // Toyota (Accessible from outside)
Bu yöntem yalnızca bir 'gelenek'tir ve pratiğe bakıldığında, özelliklere yine de dışarıdan erişilebilir.
Özel özelliklerin kapamalar kullanılarak uygulanması
Fonksiyon kapsamı ile kapamalar kullanılarak özel özellikler elde etmek de mümkündür.
1function createPerson(name) {
2 let _name = name; // Private variable within function scope
3
4 return {
5 getName: function() {
6 return _name;
7 },
8 setName: function(newName) {
9 _name = newName;
10 }
11 };
12}
13
14const person = createPerson("Alice");
15console.log(person.getName()); // Alice
16person.setName("Bob");
17console.log(person.getName()); // Bob
18
19// Cannot access directly from outside
20console.log(person._name); // undefined
Bu yöntemle, _name
değişkeni fonksiyon kapsamına alınır ve dışarıdan doğrudan erişilemez.
Özet
JavaScript'teki özel özellikler, sınıf ve nesne tasarımında kapsülleme sağlamak için çok etkili olup verilerin güvenli bir şekilde korunmasına yardımcı olur. ES2020'de tanıtılan özel alanlar için #
notasyonu, geleneksel yaklaşımlar ve kapamalara kıyasla daha net ve daha güvenli bir gizlilik yönetimi yöntemi sunar.
JavaScript'te Opsiyonel Bağlama
Opsiyonel Bağlama, JavaScript'te derinlemesine iç içe geçmiş nesnelerin özelliklerine erişmek için çok kullanışlı bir sözdizimidir. Belirli özelliklerin varlığını tek tek kontrol etmek zorunda kalmadan güvenli bir şekilde erişim sağlayarak kod okunabilirliği ve sürdürülebilirliğini artırır.
Opsiyonel Bağlama'nın Temel Sözdizimi
Opsiyonel Bağlama, özellik erişiminde kullanılan nokta (.
) veya köşeli parantez notasyonundan önce ?
koyarak kullanılabilir. Bu notasyon, dolaşılan bir özellik null
veya undefined
olduğunda undefined
döndürür, böylece program hata atmadan güvenli bir şekilde işlemeye devam edebilir.
Örnek:
1const user = {
2 name: 'John',
3 address: {
4 street: '123 Main St',
5 city: 'New York'
6 }
7};
8
9// Without using optional chaining
10const city = user && user.address && user.address.city;
11console.log(city); // New York
12
13// Using optional chaining
14const cityWithOptionalChaining = user?.address?.city;
15console.log(cityWithOptionalChaining); // New York
Bu örnekte, user
nesnesinin address
ve onun city
özelliğine erişiyoruz. Opsiyonel zincirleme kullanmadan, birden fazla varlık kontrolü yapmanız gerekirdi, ancak opsiyonel zincirleme ile bir mülkü tek bir ifadeyle güvenli bir şekilde erişebilirsiniz.
Diziler ve fonksiyonlarla Opsiyonel Zincirleme Kullanımı
Opsiyonel zincirleme yalnızca nesne özellikleri için değil, aynı zamanda dizi öğeleri ve fonksiyon çağrıları için de geçerlidir.
Dizilerle örnek:
1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser); // undefined
Fonksiyonlarla örnek:
1const user = {
2 greet: function() {
3 return 'Hello!';
4 }
5};
6
7// Call the function only if greet exists
8const greeting = user.greet?.();
9console.log(greeting); // Hello!
10
11// Return undefined if greet does not exist
12const nonExistentGreeting = user.nonExistentMethod?.();
13console.log(nonExistentGreeting); // undefined
Opsiyonel Zincirleme'yi varsayılan değerlerle birleştirme
Opsiyonel zincirleme kullanılırken, bir mülk mevcut değilse varsayılan değerleri belirtmek için genellikle mantıksal VEYA (||
) veya nullish birleştirme operatörü (??
) kullanılır.
Örnek:
1const user = {
2 name: 'John',
3 address: {
4 city: 'New York'
5 }
6};
7
8// Set a default value for a non-existent property
9const state = user?.address?.state || 'Unknown';
10console.log(state); // Unknown
11
12// Example using the nullish coalescing operator
13const zipCode = user?.address?.zipCode ?? '00000';
14console.log(zipCode); // 00000
||
operatörü false
, 0
, ''
, vb. gibi değerleri yanlış kabul ederken, ??
operatörü yalnızca işlenen null
veya undefined
ise varsayılan değeri kullanır.
Opsiyonel Zincirleme'nin Faydaları
- İç içe geçmiş nesnelere güvenli erişim: Opsiyonel zincirleme kullanarak, açık varlık kontrolleri yapmanız gerekmez ve bu da kodu daha özlü hale getirir.
- Hatalardan kaçınma: Bir mülk
null
veyaundefined
olsa bile çalışma zamanı hatalarını önleyebilir. - Okunabilirlik ve sürdürülebilirlik geliştirilir: Özellikle birçok iç içe geçmiş nesneyle uğraşırken, kodun okunabilirliği büyük ölçüde artar.
Opsiyonel Zincirleme ile İlgili Dikkat Edilmesi Gerekenler
- Opsiyonel zincirlemenin sık kullanımı, veri yapısının tasarımının aşırı karmaşık olduğunun bir işareti olabilir. Basit bir veri modeli oluşturmak için çaba göstermelisiniz.
- Bazı eski tarayıcılar ve JavaScript motorları bunu desteklemediğinden, polyfill'ler veya transpiler'lar kullanmanız gerekebilir.
Sonuç
Opsiyonel zincirleme, JavaScript'te iç içe geçmiş nesnelerin özelliklerine ve fonksiyonlarına güvenli erişimi basitleştiren güçlü bir özelliktir. Derinlemesine iç içe geçmiş veri yapılarına erişirken özellikle etkilidir, hata önleme ve geliştirilmiş kod okunabilirliği sağlar.
Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.