Mövzunu Açan
#0
Modern JavaScript ES2025 Özellikleri
JavaScript dünyası, bildiğiniz gibi, sürekli bir evrim içinde. Her yıl yeni özellikler, sentaks iyileştirmeleri ve API'lar hayatımıza giriyor. ES2025 adını verdiğimiz bu yeni iterasyon (ki aslında her yılın Haziran ayında yeni bir sürüm onaylanır ve bu sürümün adı o yıla göre belirlenir, yani bahsettiğimiz özellikler ES2024'te, hatta ES2023'te onaylanmış veya ES2025'e aday Stage 3 teklifler de olabilir), geliştiricilerin günlük yaşamını kolaylaştıran, kod kalitesini artıran ve performansı optimize eden pek çok yenilikle geliyor. Peki, bu yenilikler bize ne vaat ediyor, kodlarımızı nasıl etkileyecek? Gelin, hep birlikte bu heyecan verici gelişmelere bir göz atalım.
Değişmez Dizi Metotları: Yan Etkilerden Kurtulmak
JavaScript'te dizilerle çalışırken en çok karşılaşılan durumlardan biri, orijinal diziyi değiştirmeden (mutasyon yapmadan) yeni bir dizi oluşturma ihtiyacıdır. Eskiden bunun için ile kopyalama yapıp ardından veya gibi metotları kullanırdık ya da spread operatörünü () devreye sokardık. Ancak şimdi, ES2023 ile hayatımıza giren toReversed(), toSorted(), toSpliced() ve with() gibi yeni metotlar sayesinde bu süreç çok daha zarif ve okunur hale geldi. Bu metotlar, isimlerindeki "to" ön ekiyle de anlaşıldığı gibi, orijinal diziyi değiştirmek yerine her zaman yeni bir dizi döndürüyorlar. Bu da özellikle React gibi durum yönetimi gerektiren kütüphanelerde veya saf fonksiyonel programlama prensiplerini benimseyen mimarilerde büyük kolaylık sağlıyor.
Örneğin, bir diziyi tersine çevirmek istediğinizde:
Eskiden metodu orijinal diziyi doğrudan değiştirirdi, ki bu da beklenmedik yan etkilere yol açabilirdi. Artık bu dertten kurtulduk diyebiliriz. Ya da bir diziyi sıralamak isterseniz:
metodunun da aynı şekilde orijinal diziyi değiştirdiğini hatırlarsak, ile bu sorunu kökten çözmüş oluyoruz. Peki ya belirli bir indeksteki öğeyi değiştirmek istersek? İşte burada with() metodu devreye giriyor:
Bu metotlar, kodunuzu daha öngörülebilir ve hata ayıklaması daha kolay hale getiriyor. Mutasyonlardan kaçınmak, özellikle büyük ve karmaşık uygulamalarda performansı ve güvenilirliği artırmanın anahtarıdır.
at() Metodu: Dizilerde ve Dizgilerde Yeni Bir Erişim Standardı
Dizilerde veya dizgilerde belirli bir indekse erişmek için genellikle köşeli parantez () kullanırız. Ancak sondan elemanlara erişmek istediğimizde işler biraz karmaşıklaşıyordu. Örneğin, bir dizinin son elemanına erişmek için yazmak zorunda kalırdık. ES2022 ile gelen at() metodu, bu duruma şık bir çözüm sunuyor. Artık hem baştan hem de sondan elemanlara çok daha temiz bir şekilde erişebiliyoruz.
Pozitif indekslerle kullanımı:
Negatif indekslerle kullanımı (sondan sayar):
Bu metot sadece diziler için değil, dizgiler için de geçerli. Bir dizginin son karakterine kolayca erişmek istediğinizde ne kadar kullanışlı olduğunu göreceksiniz. Basit ama etkili bir iyileştirme, değil mi? Kodunuzu daha kısa ve okunur hale getirme konusunda küçük ama önemli bir adım.
Üst Düzey await: Modüllerin Asenkron Doğası
Asenkron programlama, JavaScript'in temel taşlarından biri haline geldi. anahtar kelimeleri sayesinde karmaşık asenkron işlemleri çok daha okunur ve yönetilebilir bir şekilde yazabiliyoruz. Ancak, anahtar kelimesini sadece bir fonksiyonunun içinde kullanabiliyorduk. Bu durum, özellikle modül yüklemesi sırasında asenkron işlemler yapmamız gerektiğinde bazı kısıtlamalar yaratıyordu. ES2022 ile gelen Üst Düzey await (Top-Level await) özelliği, bu kısıtlamayı ortadan kaldırıyor. Artık modüllerin en üst seviyesinde doğrudan kullanabiliyoruz.
Bu ne anlama geliyor? Modülünüzün dışa aktardığı değerleri veya gerçekleştirdiği işlemleri başlatmadan önce asenkron bir bağımlılığın tamamlanmasını bekleyebiliriz. Örneğin, bir API'dan konfigürasyon çekmek veya bir veritabanı bağlantısı kurmak gibi işlemleri modülün kendisi yüklenirken yapabiliriz.
Bu sayede, değişkeni, fonksiyonu tamamlanana kadar diğer modüller tarafından kullanılamayacak, bu da bağımlılıkların doğru sırada çözülmesini sağlıyor. Ancak dikkatli olmakta fayda var: Üst düzey kullanan bir modül, onu içe aktaran diğer modüllerin yürütülmesini de durduracaktır. Bu durum, uygulamanızın başlangıç süresini etkileyebilir. Yani, bu özelliği kullanırken performans etkilerini göz önünde bulundurmak ve gereksiz yere kullanmaktan kaçınmak önemli. Ama doğru yerde kullanıldığında, kodunuzu inanılmaz derecede sadeleştiren güçlü bir araç.
Dekoratörler (Decorators): Meta Programlamanın Gücü
JavaScript'e uzun süredir beklenen ve nihayet Stage 3'e ulaşmış, yani yakın gelecekte standartlaşması beklenen en heyecan verici özelliklerden biri de Dekoratörler (Decorators). Dekoratörler, sınıflara, metotlara, özelliklere veya parametrelere belirli davranışlar veya meta veriler eklememizi sağlayan özel türde fonksiyonlardır. Bu sayede kod tekrarını azaltabilir, daha modüler ve okunur yapılar oluşturabiliriz. Aslında, Angular veya TypeORM gibi bazı popüler framework'lerde bu konseptin TypeScript versiyonlarını zaten görüyoruz. JavaScript standartlarına girmesiyle birlikte, bu tür yetenekler doğrudan dilin kendisinde yer alacak.
Bir dekoratör, bir fonksiyon gibi davranır ve hedef öğeyi (sınıf, metot vb.) argüman olarak alır, ardından bu öğeyi değiştirilmiş veya genişletilmiş bir versiyonunu döndürür. Düşünsenize, bir metodun çağrılma süresini otomatik olarak loglamak istiyorsunuz. Eskiden her metodun içine manuel olarak ve yazmanız gerekirdi. Dekoratörler ile bu işi tek bir satırda halledebilirsiniz:
Yukarıdaki örnekte bir metot dekoratörü olarak üzerine uygulanıyor. Bu sayede, metodun orijinal mantığına dokunmadan, sadece bir satır ekleyerek çalışma süresini loglayabiliyoruz. Veritabanı işlemleri için yetkilendirme kontrolü, önbellekleme, validasyon gibi birçok ortak görevi dekoratörler aracılığıyla merkezi ve tekrar kullanılabilir bir şekilde yönetebiliriz. Bu, meta programlamanın gücünü doğrudan JavaScript'e taşıyan ve kod tabanınızın bakımını ve genişletilebilirliğini önemli ölçüde artıran bir özellik. Öğrenmesi biraz zaman alabilir ama getireceği faydalar kesinlikle buna değer.
Hata Nedenleri (Error Cause): Daha Anlamlı Hata Yönetimi
JavaScript'te hata yakalama ve yönetimi, uygulamanın sağlamlığı için kritik öneme sahiptir. Bazen bir hatanın temel nedeni başka bir hatadan kaynaklanır. Örneğin, bir ağ isteği başarısız olduğunda, bu isteğin neden başarısız olduğunu (örneğin, sunucuya ulaşılamaması veya yetkilendirme hatası) üst seviyede yakaladığımız hataya eklemek isteyebiliriz. ES2022 ile gelen Error Cause özelliği, bu senaryo için zarif bir çözüm sunuyor. Artık bir nesnesi oluştururken, seçeneğini kullanarak orijinal hatayı yeni bir hataya bağlayabiliriz.
[CODE]
async function veriCek() {
try {
const response = await fetch('https://api.ornek.com/veriler');
if (!response.ok) {
throw new Error('API yanıtı başarısız oldu.', { cause: { status: response.status, url: response.url } });
}
return await response.json();
} catch (
JavaScript dünyası, bildiğiniz gibi, sürekli bir evrim içinde. Her yıl yeni özellikler, sentaks iyileştirmeleri ve API'lar hayatımıza giriyor. ES2025 adını verdiğimiz bu yeni iterasyon (ki aslında her yılın Haziran ayında yeni bir sürüm onaylanır ve bu sürümün adı o yıla göre belirlenir, yani bahsettiğimiz özellikler ES2024'te, hatta ES2023'te onaylanmış veya ES2025'e aday Stage 3 teklifler de olabilir), geliştiricilerin günlük yaşamını kolaylaştıran, kod kalitesini artıran ve performansı optimize eden pek çok yenilikle geliyor. Peki, bu yenilikler bize ne vaat ediyor, kodlarımızı nasıl etkileyecek? Gelin, hep birlikte bu heyecan verici gelişmelere bir göz atalım.
Değişmez Dizi Metotları: Yan Etkilerden Kurtulmak
JavaScript'te dizilerle çalışırken en çok karşılaşılan durumlardan biri, orijinal diziyi değiştirmeden (mutasyon yapmadan) yeni bir dizi oluşturma ihtiyacıdır. Eskiden bunun için
CODE
1slice()CODE
1map()CODE
1filter()CODE
1...Örneğin, bir diziyi tersine çevirmek istediğinizde:
CODE
1234
const sayilar = [1, 2, 3, 4, 5];
const tersSayilar = sayilar.toReversed(); // Yeni dizi: [5, 4, 3, 2, 1]
console.log(sayilar); // Orijinal dizi değişmedi: [1, 2, 3, 4, 5]
Eskiden
CODE
1reverse()CODE
1234
const meyveler = ['elma', 'muz', 'çilek', 'armut'];
const siraliMeyveler = meyveler.toSorted(); // Yeni dizi: ['armut', 'çilek', 'elma', 'muz']
console.log(meyveler); // Orijinal dizi yine aynı: ['elma', 'muz', 'çilek', 'armut']
CODE
1sort()CODE
1toSorted()CODE
12345
const renkler = ['kırmızı', 'yeşil', 'mavi'];
const yeniRenkler = renkler.with(1, 'sarı'); // 1. indeksteki (yeşil) öğeyi sarı ile değiştirir
console.log(yeniRenkler); // Yeni dizi: ['kırmızı', 'sarı', 'mavi']
console.log(renkler); // Orijinal dizi: ['kırmızı', 'yeşil', 'mavi']
Bu metotlar, kodunuzu daha öngörülebilir ve hata ayıklaması daha kolay hale getiriyor. Mutasyonlardan kaçınmak, özellikle büyük ve karmaşık uygulamalarda performansı ve güvenilirliği artırmanın anahtarıdır.
at() Metodu: Dizilerde ve Dizgilerde Yeni Bir Erişim Standardı
Dizilerde veya dizgilerde belirli bir indekse erişmek için genellikle köşeli parantez (
CODE
1array[index]CODE
1array[array.length - 1]Pozitif indekslerle kullanımı:
CODE
1234
const harfler = ['a', 'b', 'c', 'd'];
console.log(harfler.at(0)); // 'a'
console.log(harfler.at(2)); // 'c'
Negatif indekslerle kullanımı (sondan sayar):
CODE
123
console.log(harfler.at(-1)); // 'd' (son eleman)
console.log(harfler.at(-2)); // 'c' (sondan ikinci eleman)
Bu metot sadece diziler için değil, dizgiler için de geçerli. Bir dizginin son karakterine kolayca erişmek istediğinizde ne kadar kullanışlı olduğunu göreceksiniz. Basit ama etkili bir iyileştirme, değil mi? Kodunuzu daha kısa ve okunur hale getirme konusunda küçük ama önemli bir adım.
Üst Düzey await: Modüllerin Asenkron Doğası
Asenkron programlama, JavaScript'in temel taşlarından biri haline geldi.
CODE
1async/awaitCODE
1awaitCODE
1asyncCODE
1awaitBu ne anlama geliyor? Modülünüzün dışa aktardığı değerleri veya gerçekleştirdiği işlemleri başlatmadan önce asenkron bir bağımlılığın tamamlanmasını bekleyebiliriz. Örneğin, bir API'dan konfigürasyon çekmek veya bir veritabanı bağlantısı kurmak gibi işlemleri modülün kendisi yüklenirken yapabiliriz.
CODE
1234567891011
// config.js
const fetchConfig = async () => {
const response = await fetch('/api/config');
const config = await response.json();
return config;
};
export const appConfig = await fetchConfig(); // Üst düzey await kullanımı!
console.log('Konfigürasyon yüklendi:', appConfig);
Bu sayede,
CODE
1appConfigCODE
1fetchConfigCODE
1awaitDekoratörler (Decorators): Meta Programlamanın Gücü
JavaScript'e uzun süredir beklenen ve nihayet Stage 3'e ulaşmış, yani yakın gelecekte standartlaşması beklenen en heyecan verici özelliklerden biri de Dekoratörler (Decorators). Dekoratörler, sınıflara, metotlara, özelliklere veya parametrelere belirli davranışlar veya meta veriler eklememizi sağlayan özel türde fonksiyonlardır. Bu sayede kod tekrarını azaltabilir, daha modüler ve okunur yapılar oluşturabiliriz. Aslında, Angular veya TypeORM gibi bazı popüler framework'lerde bu konseptin TypeScript versiyonlarını zaten görüyoruz. JavaScript standartlarına girmesiyle birlikte, bu tür yetenekler doğrudan dilin kendisinde yer alacak.
Bir dekoratör, bir fonksiyon gibi davranır ve hedef öğeyi (sınıf, metot vb.) argüman olarak alır, ardından bu öğeyi değiştirilmiş veya genişletilmiş bir versiyonunu döndürür. Düşünsenize, bir metodun çağrılma süresini otomatik olarak loglamak istiyorsunuz. Eskiden her metodun içine manuel olarak
CODE
1console.time()CODE
1console.timeEnd()CODE
12345678910111213141516171819202122232425
function logExecutionTime(target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args) {
const start = performance.now();
const result = await originalMethod.apply(this, args);
const end = performance.now();
console.log([icode]Metot '${propertyKey}' ${end - start} ms sürdü.[/icode]);
return result;
};
return descriptor;
}
class Hesaplama {
[user]logExecutionTime[/user]
async cokIslemYapanMetot(a, b) {
// Karmaşık bir işlem simülasyonu
return new Promise(resolve => setTimeout(() => resolve(a + b), 100));
}
}
const hesaplayici = new Hesaplama();
hesaplayici.cokIslemYapanMetot(5, 10).then(sonuc => console.log('Sonuç:', sonuc));
Yukarıdaki örnekte
CODE
1@logExecutionTimeCODE
1cokIslemYapanMetotHata Nedenleri (Error Cause): Daha Anlamlı Hata Yönetimi
JavaScript'te hata yakalama ve yönetimi, uygulamanın sağlamlığı için kritik öneme sahiptir. Bazen bir hatanın temel nedeni başka bir hatadan kaynaklanır. Örneğin, bir ağ isteği başarısız olduğunda, bu isteğin neden başarısız olduğunu (örneğin, sunucuya ulaşılamaması veya yetkilendirme hatası) üst seviyede yakaladığımız hataya eklemek isteyebiliriz. ES2022 ile gelen Error Cause özelliği, bu senaryo için zarif bir çözüm sunuyor. Artık bir
CODE
1ErrorCODE
1{ cause: someOtherError }[CODE]
async function veriCek() {
try {
const response = await fetch('https://api.ornek.com/veriler');
if (!response.ok) {
throw new Error('API yanıtı başarısız oldu.', { cause: { status: response.status, url: response.url } });
}
return await response.json();
} catch (