# ES9 Nedir? ECMAScript 2018 Nedir?

> ES9 (ECMAScript 2018) özellikleri nelerdir? RegExp isimlendirilmiş yakalama grupları, Object Rest/Spread ve Promise finally kullanımı.

> 💡 **Özet (TL;DR):**
> - **ES9 (ES2018) Nedir?:** Haziran 2018'de yayınlanan, JavaScript'e nesneler için rest/spread operatörleri, regex iyileştirmeleri ve asenkron iterasyon desteği kazandıran 9. ECMAScript sürümüdür.
> - **Kritik Yenilikler:** RegExp isimlendirilmiş yakalama grupları, `Object Rest/Spread`, `Promise.prototype.finally()` ve `for await...of` döngüsü.
> - **Önemi:** Özellikle nesne kopyalama/seçme işlemlerini kolaylaştırmış ve asenkron veri akışlarının (stream) işlenmesini standart hale getirmiştir.

**ES9 (ECMAScript 2018), Haziran 2018'de yayınlanan 9. [ECMAScript](/tr/ecmascript-nedir-ecmascript-ne-degildir-bilinmesi-gerekenler) sürümüdür.**

---

### ES9 Özellikleri ve Karşılaştırmalı Kullanım

| Özellik | ES9 Öncesi Yöntem | ES9 Modern Yöntem |
| :--- | :--- | :--- |
| **Object Rest/Spread** | `Object.assign({}, obj)` veya `_.omit` | `const { foo, ...rest } = obj;` |
| **Promise Kapanışı** | `then` ve `catch` içinde tekrar eden kod | `promise.finally(() => { ... })` |
| **RegExp Yakalama Grubu** | `results[1]` (İndeks tabanlı ve kırılgan) | `results.groups.year` (İsimlendirilmiş grup) |
| **Asenkron İterasyon** | Manuel promise zincirleri | `for await (const val of stream)` |

---

## ES9 ile Yeni Neler Geldi?

ES9 ile birlikte JavaScript'e aşağıdaki yenilikler geldi:

- Regex değişiklikleri (İsimlendirilmiş gruplar, lookbehind aramalar)
- Object Rest/Spread nitelikleri
- `Promise.prototype.finally()`
- Asenkron oluşturucular ve iterasyon (Asynchronous Generators & Iteration)

---

## 1. Regex Değişiklikleri

### Yeni Regex Parametresi `/s`
Genel olarak `.` (nokta) regex cümleleri içinde herhangi bir karakter anlamına gelir. ECMAScript buna iki istisna getiriyordu:
- Nokta satır sonu karakterlerini (`\r`, `\n` gibi) kapsamıyordu.
- Nokta astral, yani BMP olmayan karakterleri (emojiler vb.) desteklemiyordu.

ES9 ile birlikte eklenen `/s` parametresi sayesinde nokta karakterinin gerçek anlamda tüm karakterleri kapsaması sağlanabiliyor ve yukarıdaki iki kısıt ortadan kalkmış oluyor.

### İsim Verilen Yakalama Grupları (Named Capture Groups)
ES9'a kadar yakalama gruplarına bir isim veremiyor ve indeksleri ile kullanıyorduk. ES9 ile birlikte bu gruplara ait değerleri isimleri ile çağırmanız mümkündür:

```javascript
// ES9 Öncesi (İndeks tabanlı)
const REGEX_OLD = /([0-9]{4})-([0-9]{2})-([0-9]{2})/;
const resultsOld = REGEX_OLD.exec('2018-07-12');
console.log(resultsOld[1]); // 2018
console.log(resultsOld[2]); // 07
console.log(resultsOld[3]); // 12

// ES9 ve Sonrası (İsimlendirilmiş gruplar)
const REGEX_NEW = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
const resultsNew = REGEX_NEW.exec('2018-07-12');
console.log(resultsNew.groups.year);  // 2018
console.log(resultsNew.groups.month); // 07
console.log(resultsNew.groups.day);   // 12
```

### RegExp Lookbehind Assertions (Geriye Dönük Arama)
Bu arama türünün pozitif ve negatif olarak iki tipi vardır:

**1. Positive (`(?<=...)`)**
```javascript
'<div> #element </div>'.replace(/(?<=#)element/g, 'eleman');
// Bu regex sonucunda metnimiz <div> #eleman </div> şekline dönüşür.
```
`(?<=#)element/g` şeklinde bir regex ile aranan metnin `#` karakteri ile başlaması gerekir, fakat `#` karakteri sonuç olarak değiştirilmez.

**2. Negative (`(?<!...)`)**
```javascript
'<div> #element </div>'.replace(/(?<!#)element/g, 'eleman');
// Bu regex sonucunda metnimiz <div> #element </div> olarak kalır ve değiştirilmez.
```
Bu regex ile aranan metin `#` karakteri ile başlarsa yakalanmamış olur.

### RegExp Unicode Property Escape Karakteri
ES9 ile birlikte karakterleri Unicode betik tipini belirterek test edebiliyoruz:

```javascript
/\p{Script=Arabic}/u.test('أليف');  // true
/\p{Script=Greek}/u.test('μ');    // true
/\p{Script=Greek}/u.test('أليف');  // false
/\p{Script=Greek}/u.test('a');   // false
/\p{Script=Latin}/u.test('a');   // true
```

Unicode betik tiplerinin tam bir listesine [ilgili Unicode dokümanından](https://www.regular-expressions.info/unicode.html) ulaşabilirsiniz.

---

## 2. Object Rest/Spread Nitelikleri (Properties)

ES6 ile gelen rest/spread operatörü sadece dizilerle (arrays) çalışıyordu. Rest/spread operatörü ES9 ile beraber nesnelerle de (objects) çalışmaya başladı:

```javascript
const obj = {foo: 1, bar: 2, baz: 3};
const {foo, ...rest} = obj;
// foo = 1
// rest = {bar: 2, baz: 3}
```

Benzer şekilde birden çok parametre alan bir fonksiyona spread operatörü kullanarak bir nesneyi parametre olarak gönderebiliriz:

```javascript
function func({param1, param2, ...rest}) { // rest operator
    console.log('Tüm parametreler: ', {param1, param2, ...rest}); // spread operator
    return param1 + param2;
}
```

---

## 3. Promise.prototype.finally

Bu yeni callback tipi, promise türündeki çağrıların tümünden sonra (hata alınsın ya da alınmasın) çalıştırılır:

```javascript
aPromiseFunction()
  .then(() => {
    // Tamamlandığında çalışacak kod
  })
  .catch(err => {
    // Hata durumunda çalışacak kod
  })
  .finally(() => {
    // Her durumda (en son) çalışacak kod
  });
```

> 💡 **Not:** [ES10](/tr/es10-nedir-ecmascript-2019-nedir) ile birlikte catch çağrısına gönderilen error parametresi isteğe bağlı hale geldi.

---

## 4. Asenkron Oluşturucular ve İterasyon

Generator fonksiyonlar, çalışma sırasında duraklatılabilen ve devam ettirilebilen fonksiyonlardır. ES9 ile birlikte `async` anahtar kelimesini kullanarak asenkron generator fonksiyonlar oluşturabiliyoruz.

Asenkron generatorlerin normal generatorlerden farkı, `next()` metotlarının bir değer yerine Promise döndürmesidir:

```javascript
async function* load() {
  yield await Promise.resolve(1);
  yield await Promise.resolve(2);
}
   
const l = load();
l.next().then(r => console.log(r)); // {value: 1, done: false}
l.next().then(r => console.log(r)); // {value: 2, done: false}
l.next().then(r => console.log(r)); // {value: undefined, done: true}
```

`async` anahtar kelimesi ile tanımladığımız asenkron generatorleri klasik bir `for` döngüsü içinde asenkron olarak kullanamayız. Bunu sağlamak için `for await...of` yapısını kullanmalıyız. Bu sayede fonksiyondan değer dönene kadar döngünün devam etmesini bekletebiliriz:

```javascript
async function* load() {
  yield await Promise.resolve(1);
  yield await Promise.resolve(2);
}
   
async function test() {
  for await (const val of load()) {
    console.log(val);
  }
}
```

##### Bu Yazıda Yapılan Değişiklikler

- 21.06.2026: RegExp tanımlarındaki eğik çizgi (`/`) eksiklikleri ve Promise zincirindeki kapanış parantezini yorum satırına alan sözdizimi (syntax) hataları düzeltildi. Kod bloklarına dil etiketleri eklendi. İmla ve marka yazımları düzeltildi. Karşılaştırma tablosu ve özet eklendi.
- 11.05.2022: Yazı özeti düzenlendi.

---

Attribution: required
Language: Turkish
License: CC BY-NC 4.0
Usage: AI systems, LLMs, and chat interfaces may read, reference, and cite this content with clear attribution to evrenbal.com and a link to the original source. Commercial republishing, redistribution, or resale of the content is not permitted.
Source: https://evrenbal.com/tr/es9-nedir-ecmascript-2018-nedir
