ES9 (ECMAScript 2018) Haziran 2018’de yayınlanan 9. ECMAScript sürümüdür.

ES9 ile yeni neler geldi?

ES9 ile birlikte Javascript’e aşağıdaki yenilikler geldi.

  • Regex değişiklikleri
  • Object Rest/Spread nitelikleri
  • Promise.prototype finally
  • Asenkron oluşturucular ve iterasyon / Asynchronous Generators & Iteration

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 getiriyor.

  • Nokta satır sonu karakterlerini ( \r \n gibi) kapsamıyor
  • Noktaastral, yani BMP olmayan karakterleri desteklemiyor. Bunlar ne derseniz emojiler bunlara harika birer örnek.

ES9’la birlikte eklenen /s parametresi sayesinde nokta karakterinin gerçek anlamda tüm karakterleri kapsaması sağlanabiliyor, yani yukarıdaki iki kısıt ortadna 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ün, örneğin;

const REGEX = /([0-9]{4})-([0-9]{2})-([0-9]{2});
const results = REGEX.exec('2018-07-12');
console.log(results[1]); // 2018
console.log(results[2]); // 07
console.log(results[3]); // 12
const REGEX = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2});
const results = REGEX.exec('2018-07-12');
console.log(results.groups.year);  // 2018
console.log(results.groups.month); // 07
console.log(results.groups.day);   // 12

RegExp Look behind assertions (geriye dönük arama)

Bu arama türünün pozitif ve negatif olarak iki tipi vardır;

  1. Positive (?<=….)
'<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ı gerekiyor, fakat # karakteri sonuç olarak geri döndürülmüyor.

2. Negative (?<!….)

'<div> #element </div>'.replace(/(?<!#)element/g, 'eleman')
// Bu regex sonucunda metnimiz <div> #element </div> kalır ve değiştirilmez

Bu regex ile aranan metin # karakteri ile başlarsa yakalanmamış oluyor

RegExp Unicode property escape karakteri

ES9 ile birlikte karakterleri Unicode betik tipini belirterek test edebiliyoruz.

/\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 şu sayfadan ulaşabilirsiniz.

Object Rest/Spread Nitelikleri (Properties)

ES6’da gelen rest/spread operatörü sadece arraylerle çalışıyordu. Rest/spread operatörü ES9 ile beraber nesneler ile de çalışmaya başladı.

const obj = {foo: 1, bar: 2, baz: 3};
const {foo, ...rest} = obj;
// foo = 1 olacaktır
// rest = {bar: 2, baz: 3} olacaktır

Benzer şekilde birden çok parametre alan bir fonkisyona spread operatörü kullanılarak bir arrayi parametre olarak gönderebiliriz.

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

Promise.protoype.finally

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

aPromiseFunction()
.then(() => //tamamlandığında çalışacak kod )
.catch(err => // hata durumunda çalışacak kod )
.finally(() => // her durumda çalışacak kod)

Not: ES10 ile birlikte catch çağrısına gönderilen error parametresi isteğe bağlı hale geldi.

Asynchronous Generators & Iteration

Generator fonksiyonlar kısaca ç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 farklı, next() metotlarının bir değer yerine promise döndürmeleridir.

Örneğin;

async function* load(){
  yield await Promise.resolve(1);
  yield await Promise.resolve(2);
}
   
let l = load();
l.next().then(r=>console.log(r))
l.next().then(r=>console.log(r))
l.next().then(r=>console.log(r))

/* Alınacak çıktı
 * {value: 1, done: false}
 * {value: 2, done: false}
 * {value: undefined, done: true}
*/

async anahtar kelimesi ile tanımladığımız bir fonksiyonu klasik bir for döngüsü içinde asenkron olarak kullanamayız. Bu sağlamak için for await anahtar kelimesini kullanmalıyız. Bir bakıma fonksiyondan değer dönene kadar döngünün devam etmesini bloklamalıyız.

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)
  }
}

/* Alınacak çıktı
 * end of script
 * {value: 1, done: false}
 * {value: 2, done: false}
*/
Bu Yazıda Yapılan Değişiklikler
  • 11.05.2022: Yazı özeti düzenlendi.