ITHub

ECMAScript 6, avagy a JavaScript következő verziójának újdonságai

ECMAScript 6, avagy a JavaScript következő verziójának újdonságai
Farkas Gábor
Farkas Gábor
| ~6 perc olvasás

Persze a cím nem teljesen pontos, hiszen a JavaScript csak egy implementációja az ECMAScript szabványnak (például az ActionScript és a JScript mellett), de mivel a legnépszerűbb, ezért talán ennyi igazán megbocsájtható. A szabvány soron következő, 6-os verziója, amely idén júniusban válik véglegessé, 2009 óta az első frissítés, és számos érdekes újdonságot tartalmaz. Ebben a posztban ezek közül mutatom be a legfontosabbakat, és arra is kitérek, miként használhatjuk ezeket már ma is.

ECMAScript 6, avagy a JavaScript következő verziójának újdonságai

A => jelölés

A => egy új, rövidebb függvényjelölés (a funkciója hasonló a C#-os megfelelőjéhez). Bár a nyíllal függvényeket deklarálunk, ezek mégsem teljesen egyenértékűek a hagyományos függvényekkel. A legfontosabb különbség talán az ún. lexikális this: a this pointer értéke itt nem attól függ, hogy hol használjuk a függvényt, hanem attól, hol definiáltuk. Fontos még megjegyezni, hogy ezek a függvények nem használhatók konstruktorként a new kulcsszóval, ill. az arguments objektum sem áll a rendelkezésünkre.

Nézzünk egy tipikus példát anonim függvénnyel, először ECMAScript 5-ben:

var numbers = [1, 5, 11];
var plusOne = numbers.map(function(num) {
  return num + 1;
});

Ugyanezt megtehetjük az új szintaxissal is, némileg tömörebben:

var numbers = [1, 5, 11];
var plusOne = numbers.map(num => num + 1);

A nyíl bevezetésének egyik elsődleges célja a this használatából eredő gyakori hibák számának csökkentése, de emellett optimalizációs célokat is szolgál.

Osztályok

A JS világába más nyelvekből érkezőknek gyakran gondot okoz, hogy nincs klasszikus osztályalapú objektum-orientáció, ehelyett prototípusokkal dolgozhatunk (aminek valójában a megszokott megközelítés egy részhalmaza, tehát a nyelv kifejezőbb a hagyományos OOP nyelveknél, ennek ellenére szokatlan lehet).

Pontosan emiatt az ECMAScript 6 bevezet egy, a népszerű nyelvekből (Java, C#) már jól megszokott osztálydeklarációs szintaxist. Így most már akár ilyesmit is alkothatunk majd:

class Student extends Person {
  constructor(name, school) {
    super(name);

    this.school = school;
  }

  getSchool() {
    return this.school;
  }
}

Az új kulcsszavak csak egyfajta vékony szintaktikai rétegként szolgálnak a prototípusok felett, de egyszerűbbé teszik a gyakori osztályminták használatát. Támogatott az öröklés, a super() hívások, konstruktorok és statikus metódusok is.

Template stringek

A JavaScriptben a string típus számos alapvető hátránnyal bír — nincsenek többsoros stringek, az alapvető formázás is nehézkes, és nincs triviális módja a stringek HTML-biztossá tételének (az injection típusú támadások elkerülése végett). Főként ezeket hivatott orvosolni ez az új nyelvi elem.

A template stringek alapvetően hagyományos testvérükhöz hasonlóan használandóak azzal a kivétellel, hogy "visszafelé-idézőjelek" (`) közé kell tenni őket:

var message = `Hello World!`;

Fontos megjegyezni, hogy a message változó típusa továbbra is string, ez a szintaxis egyfajta preprocesszorként is felfogható. Nézzünk valami izgalmasabbat.

var message = `Ez egy
több
soros
szöveg.`;

A template stringek másik új tulajdonsága a dollárjel, amely helyettesítést jelöl:

var firstName = 'Gábor';
var message = `Szia, ${firstName}`;

A legerősebb újítás azonban az ún. tagek, amik tulajdonképpen függvények, melyekkel az előbb említett előfeldolgozási folyamat testreszabható. Például:

var message = myTag`ez egy szöveg`;

A myTag itt egy általunk definiált függvény, amely a template string darabjait kapja meg paraméterül, és egy hagyományos stringet kell visszaadnia. Ez rengeteg lehetőséget rejt magában, és sok esetben biztonságosabbá teheti a kódunkat.

Szimbólumok

A szimbólumok alapvetően a privát objektumváltozók implementálására jöttek létre, amit a JavaScript fejlesztők régóta szerettek volna a nyelvben látni. Akármilyen elnevezési konvenciót is választunk, a privátként használt változók mindig hozzáférhetőek lesznek stringekkel. Nézzük az alábbi példát ECMAScript 5-ben:

function MyClass(privateData) {
  this.privateData = privateData;
}

MyClass.prototype = {
  getPrivateData: function() {
    return this.privateData;
  }
};

var c = new MyClass("valami");

Hiába szántuk a privateData-t privátnak, az hozzáférhető lesz a c["privateData"] szintaxison keresztül. Ez elkerülhető szimbólumokkal, amelyeket a Symbol kulcsszóval definiálunk:

var privateData = Symbol("privateData");

function MyClass(privateData) {
  this[privateData] = privateData;
}

(...)

Az egyetlen paraméter opcionális; elhagyása esetén a szimbólum azonos nevű lesz a változóval (itt elhagyhattuk volna).

Iterátorok és generátorok

Az iterátor objektum egy teljesen hagyományos objektum, amely (hasonlóan más nyelvekhez) implementálja a next() metódust. Ennek egy két mezővel rendelkező objektumot kell visszaadnia, ezek a value, amely az iterálandó lista következő elemét tartalmazza, a done pedig egy boolean változó, amely akkor igaz, ha a lista végére értünk. Egy így létrehozott myIterator nevű objektum a for..of szintaxissal használható (a for..in-nel analóg módon):

for (var i of iterator) {
  console.log(i);
}

Iterátorokat létrehozni ez alapján viszonylag egyszerű, de fáradságos és repetitív is. Pontosan itt jönnek a képbe a generátorok. A generátor egy olyan speciális függvény, ami egy iterátort ad vissza. Ezekhez két új nyelvi elem ad segítséget: a function * azt jelöli, hogy a függényünk egy generátor, a yield-del pedig definiálhatjuk a next() meghívásakor visszaadandó értéket. Például egy generátor, ami egy iterátort ad vissza a Fibonacci számsorozathoz:

var createFibonacci = function *() {
  var pre = 0, cur = 1;
  for (;;) {
    var temp = pre;
    pre = cur;
    cur += temp;
    yield cur;
  } 
}

Ezt a generátort aztán használhatjuk is, írjuk ki a sorozat első ezer tagját:

var iterator = createFibonacci();

for (var n of iterator) {
  if (n > 1000)
    break;

  print(n);
}

Az ECMAScript 6 számos előre definiált iterátort is tartalmaz gyakran használt elemekhez (tömbök, objektumok, mapek, stb.).

Összegzés

Ez persze csak a jéghegy csúcsa, az új szabvány számos más jobbnál jobb újdonságot is tartogat, ezekről egy nagyon jó és magyarázó összefoglaló található az ingyenes Understanding ECMAScript 6 c. könyvben.

Az ECMAScript 6-ot a legújabb böngészők már részben támogatják, aki azonban már most teljeskörűen használná, annak érdekes lehet a 6to5 nevű projekt, ami az ECMAScript 6-ban megírt programokat ECMAScript 5-re írja át, így az bárhol futtathatóvá válik.