ECMAScript
ECMAScript – stworzona przez ECMA ustandaryzowana specyfikacja obiektowego[2] języka programowania, której najbardziej znane implementacje to JavaScript, JScript i ActionScript. Specyfikacja ta oznaczona jest jako ECMA-262 i ISO/IEC 16262. Język początkowo był projektowany z myślą o pisaniu skryptów i przeniesieniu części zadań obliczeniowych na stronę klienta (przeglądarki internetowej) w architekturze klient-serwer[3], od tego czasu znacznie ewoluował i błędem byłoby nazywanie go językiem skryptowym, sami autorzy w specyfikacji nazywają go językiem programowania, który wyszedł poza skryptowanie i jest pełnoprawnym językiem programowania ogólnego zastosowania[4], wskazując na jego właściwości porównywalne do tych obecnych w Javie, Selfie, czy Scheme, które były inspiracją dla Brendana Eicha, przy tworzeniu języka JavaScript[5].
Pojawienie się |
1997 |
---|---|
Paradygmat |
Język skryptowy wieloparadygmatowy (obiektowy, funkcyjny, imperatywny) |
Typowanie | |
Implementacje |
JavaScript, SpiderMonkey, V8, JavaScriptCore, Chakra, Rhino, Carakan, KJS |
Aktualna wersja stabilna |
ECMAScript 2021[1] (czerwiec 2021) |
Twórca | |
Platforma sprzętowa | |
Strona internetowa |
ECMA-262 definiuje samą semantykę języka oraz niektóre podstawowe typy danych (String
, Boolean
, Number
, Object
itp.) i obiekty (np. Math
, Array
). Elementy, takie jak obiektowy model dokumentu, specjalne funkcje wejścia-wyjścia, obsługa graficznego interfejsu użytkownika nie wchodzą w skład specyfikacji ECMAScript – definiowane są przez inne standardy (W3C DOM) lub samych autorów konkretnych implementacji.
Standard jest cały czas uaktualniany. Od 2015, co roku powstaje nowa wersja, którą zajmuje się komisja TC39, w skład której wchodzą przedstawiciele wszystkich głównych przeglądarek internetowych i kilkadziesiąt innych organizacji[6][7].
Wersje ECMAScript
edytujZaraz po powstaniu ES6 (6 lat od wersji ES5), TC39 zdecydowała się na zmianę nazewnictwa kolejnych wersji standardu. I tak wersja ES6, została nazwana ES2015. Kolejne to ES2017, ES2018 itd. Są to oficjalne nazwy wersji[8].
Więcej o różnych implementacjach i ich wersjach w artykule JavaScript.
Proces dodawania nowych funkcji do standardu opisującego JavaScript jest opisany w artykule TC39.
Wersja | Wydana | Zmiany[9] |
---|---|---|
1 | czerwiec 1997 | |
2 | czerwiec 1998 | Głównie korekta redaktorska[a] |
3 | grudzień 1999 | Wyrażenia regularne, obsługa wyjątków, nowe rodzaje pętli, literały tablic i obiektów |
4 | porzucona | Klasy, jawna kontrola dostępu, alternatywne dla DOM wbudowane wsparcie dla XML[b] |
5 – ES5 | grudzień 2009 | Tryb , obsługa JSON
|
6 – ES2015[10] | czerwiec 2015 | Zmiany składni: Klasy (class ), moduły (import ), deklaracje const i let , funkcje strzałkowe, domyślne parametry funkcji, parametr resztkowy funkcji (…args ), literały obiektowe ({zmienna1,zmienna2} ), pętle / , łańcuchy szablonowe (tekst = `Opis: ${zmienna}.`; ), destrukcyjne deklaracje i przypisanie, generatory (yield ), nowe sekwencje Unicode, sprawdzanie wywołania funkcji jako klasy (new.target )[11].
Pozostałe to m.in.: kolekcje (Set, Map itp), tablice typowane, proxies (meta obiekty)[11]. |
7 – ES2016[12] | czerwiec 2016 | Operator potęgowy ( ), [13].
|
8 – ES2017[14] | czerwiec 2017 | Funkcje i oczekiwanie przez , / , / [13].
|
9 – ES2018[15] | czerwiec 2018 | Asynchroniczne iteratory, parametr resztkowy dla właściwości obiektów, nowe funkcje wyrażeń regularnych (w tym nazwane grupy), funkcja dla obietnic[13].
|
10 – ES2019[16] | czerwiec 2019 | Metody spłaszczania tablic (flat ), zmiany w metodzie sortowania tablic i metodzie [13].
|
11 – ES2020[17] | czerwiec 2020 | Operatora opcjonalnych łańcuchów zmiennych (a?.b ) i nullowego scalania (?? ), prymityw [13].
|
12 – ES2021[1] | czerwiec 2021 | Funkcja ''.replaceAll() , Promise.any() , słabe referencje (m.in. WeakRef ), logiczne przypisania, separatory długich liczb (tysiące)[13].
|
ES2022 | czerwiec 2022 | Definiowanie właściwości klasy na poziomie klasy, statyczne właściwości klas, prywatne metody klas, Object.hasOwn , właściwość powodu wyjątku (cause ), opcja /d dla RegExp [13].
|
ES2023 | czerwiec 2023 | [].findLast , [].findLastIndex , wsparcie dla hashbang[13].
|
Podstawowe elementy składni
edytujKomentarze
edytujKomentarze w skryptach ECMAScriptu umieszcza się w sposób identyczny jak w C++. Komentarz blokowy umieszcza się między sekwencją znaków /*
a */
, komentarz liniowy rozpoczyna się sekwencją //
a kończy znakiem końca linii:
/* To jest komentarz
blokowy. Zajmuje on
kilka linii */
// to jest komentarz liniowy
Zmienne
edytujZmienne są typowane dynamicznie. Definiowanie zmiennej polega na zwykłym przypisaniu jej wartości lub zadeklarowaniu za pomocą słowa kluczowego var
. Zmienne zdefiniowane poza funkcjami oraz bez słowa kluczowego są dostępne w zasięgu globalnym (widoczne dla całej strony).
Tryb ścisły (strict mode) w ECMAScript 5 wymusza jawne deklarowanie wszystkich zmiennych.
Zmienne zdefiniowane za pomocą var
widoczne są w całej funkcji. Od ES2015 zmienne można również definiować z mniejszą widocznością za pomocą let
oraz const
. W przeciwieństwie do var
zmiennych zadeklarowanych za pomocą let
nie można redefiniować, a dla const
nie można dodatkowo przypisać innego obiektu do takiej zmiennej (chociaż można zmienić wartości w ramach tego obiektu).
Instrukcje sterujące
edytujPodstawowe instrukcje są identyczne z instrukcjami znanymi z języków Java i C++.
Instrukcja if
edytuj
if (warunki) {
instrukcje;
} else {
instrukcje;
}
Pętla while
edytuj
while (warunki) {
instrukcje;
}
Pętla do...while
edytuj
do {
instrukcje
} while (warunki);
Pętla for
edytuj
for ([instrukcje - początkowe];[warunki];[instrukcje - krokowe]) {
instrukcje - środkowe;
}
Pętla for...in
oraz for...of
edytuj
Pętla ta przechodzi przez wszystkie pola danego obiektu (w tym elementy tablicy):
for (let własność in obiekt) {
instrukcje;
}
Kolejność przechodzenia nie jest zdefiniowana w standardzie języka[18].
Pętla ta przechodzi przez wszystkie indeksy tablicy, pomijając właściwości nonenumerable:
for (let własność of obiekt) {
instrukcje;
}
Jest to instrukcja, która nie występuje w Javie (stosowny odpowiednik pojawił się dopiero w wersji JDK 1.5) natomiast jest dostępna w Borland Delphi 2005. W PHP5 jej odpowiednikiem jest instrukcja foreach
. W C++ można ją spotkać w trzech odmianach:
- jako funkcję for_each wykorzystując funktor. Warto również zwrócić uwagę na możliwość wykorzystania
for_each
z bibliotekami boost::bind oraz boost::lambda - jako konstrukcję BOOST_FOREACH z biblioteki boost
- jako pętla for bazująca na zasięgu (range-based for) wprowadzona w standardzie C++11.
Instrukcja switch
edytuj
Analogicznie jak w C, C++, PHP i Javie.
switch (wyrażenie) {
case wartość1:
instrukcje;
break;
case wartość2:
instrukcje;
break;
default:
instrukcje;
break;
}
Obiekty
edytujW ECMAScripcie istnieją obiekty i typy prymitywne. Możliwe jest jednak użycie metod z odpowiedniej otoczki – w razie potrzeby dynamicznie jest tworzona otoczka odpowiedniego typu (np.
), która od razu po wykorzystaniu jest usuwana. Podstawowym obiektem jest String
. Standard ECMA opisuje także obiekty Object
(tablica), Array
(ciąg znaków), String
(liczba całkowita lub rzeczywista), Number
(wartość logiczna), Boolean
(funkcja ECMAScriptu), Function
(data) i Date
(operacje matematyczne).
Math
Dostęp do pól i metod
edytujObiekty ECMAScriptu są tablicami asocjacyjnymi. Dostęp do pól obiektów jest możliwy przy użyciu dwóch równoważnych notacji:
i obiekt.pole
.
obiekt["pole"]
Ponieważ metody obiektu (funkcje) są jego polami, także do nich dostęp jest możliwy przy użyciu zarówno notacji z kropką, jak i notacji z nawiasami kwadratowymi. Poniższe dwie linie kodu są zatem równoważne:
m.metoda1();
m["metoda1"]();
Obie notacje z nawiasami kwadratowymi zwyczajowo stosuje się jednak przy korzystaniu z tablic powstałych jako obiekt
.
Array
Dostęp do pól i metod obiektu ułatwiała instrukcja wiążąca „
”. Nie jest ona jednak dozwolona w trybie ścisłym ECMAScript 5[19]. Poniższe konstrukcje są równoważne:
with
obiekt.pole1 = wartość;
obiekt.pole2 = wartość;
i
with (obiekt) {
pole1 = wartość;
pole2 = wartość;
}
Definiowanie klas dla obiektów
edytujAby zdefiniować własny obiekt, wystarczy utworzyć funkcję konstruktora:
// funkcja konstruktora
function MójObiekt(poleA, poleB) {
this.poleA = poleA;
this.poleB = poleB;
this.metoda1 = function() {
alert("mójObiekt::metoda1()");
};
this.metoda2 = function() {
alert("mójObiekt::metoda2()");
};
}
Podobnie, choć lżejszy obiekt można uzyskać następująco:
// funkcja konstruktora
function MójObiekt(poleA, poleB) {
this.poleA = poleA;
this.poleB = poleB;
}
// metody
MójObiekt.prototype.metoda1 = function() {
alert("mójObiekt::metoda1()");
};
MójObiekt.prototype.metoda2 = function() {
alert("mójObiekt::metoda2()");
};
Od ES2015 wprowadzono lukier składniowy do definiowania klas (pod spodem nadal używany jest prototyp):
class MójObiekt {
constructor(poleA, poleB) {
this.poleA = poleA;
this.poleB = poleB;
}
metoda1() {
alert("mójObiekt::metoda1()");
}
metoda2() {
alert("mójObiekt::metoda2()");
}
}
Aby utworzyć instancję klasy
, należy skorzystać z operatora MójObiekt
:
new
let m = new MójObiekt(2, 3);
Funkcje
edytujFunkcje w ECMAScripcie definiuje się przy użyciu słowa kluczowego function
, a jej argumenty podajemy w nawiasach:
function dodajDwieLiczby(a, b) {
return a + b;
}
Taki sam rezultat otrzymamy za pomocą:
var dodajDwieLiczby = function(a, b) {
return a + b;
}
Od ES2015 można używać tzw. funkcji strzałkowych (ang. arrow functions):
var dodajDwieLiczby = (a, b) => {
return a + b;
}
// lub krócej:
var dodajDwieLiczby = (a, b) => a + b;
Dziedziczenie
edytujW implementacjach ECMAScript dziedziczenie realizowane jest przez prototypy. Jeśli chcemy utworzyć klasę
dziedziczącą po klasie Pochodna
, ustawiamy pole Bazowa
na nową instancję klasy Pochodna.prototype
:
Bazowa
function Bazowa() {
this.metodaA = function() {
console.log("Bazowa::A()");
};
this.metodaB = function() {
console.log("Bazowa::B()");
};
}
function Pochodna() {
// metodaB nadpisuje odpowiednią metodę z klasy Bazowa:
this.metodaB = function() {
console.log("Pochodna::B()");
};
}
Pochodna.prototype = new Bazowa();
x = new Bazowa();
y = new Pochodna();
x.metodaA(); // wyświetla: „Bazowa::A()”
y.metodaA(); // wyświetla: „Bazowa::A()”
x.metodaB(); // wyświetla: „Bazowa::B()”
y.metodaB(); // wyświetla: „Pochodna::B()”
Od ES2015 dostępne jest extends
:
class Bazowa {
metodaA () {
console.log("Bazowa::A()");
}
metodaB () {
console.log("Bazowa::B()");
}
}
class Pochodna extends Bazowa {
constructor() {
super();
}
// metodaB nadpisuje odpowiednią metodę z klasy Bazowa:
metodaB () {
console.log("Pochodna::B()");
}
}
const x = new Bazowa();
const y = new Pochodna();
x.metodaA(); // wyświetla: „Bazowa::A()”
y.metodaA(); // wyświetla: „Bazowa::A()”
x.metodaB(); // wyświetla: „Bazowa::B()”
y.metodaB(); // wyświetla: „Pochodna::B()”
Zmienne klas
edytuj
Podobnie jak funkcje klasy również są obiektami, które można przypisać do zmiennych. Inaczej jednak niż w wypadku funkcji class Bazowa
tworzy zmienną Bazowa, której nie można redefiniować[20]. Możliwe jest jednak użycie var
:
var Bazowa = class {};
var Pochodna = class extends Bazowa {};
var Bazowa = class {
metodaA () { console.log('Bazowa::A()') }
};
var poc = new Pochodna();
var baz = new Bazowa();
console.log('poc1', typeof poc.metodaA) // undefined
console.log('baz1', typeof baz.metodaA) // function
var Pochodna = class extends Bazowa {};
var poc = new Pochodna();
console.log('poc2', typeof poc.metodaA) // function
Obsługa wyjątków
edytujDo obsługi wyjątków w ECMAScripcie wykorzystywana jest „klasa”
, odpowiadająca znanej z Javy klasie Error
.
Exception
Aby wyrzucić nowy wyjątek, należy skorzystać z instrukcji
:
throw
function zjedz() {
throw new Error("Komunikat wyjątku");
}
Aby obsłużyć wyjątek, należy zastosować konstrukcję try...catch...finally
(przy czym finally
jest opcjonalne):
try {
zjedz();
} catch (wyjątek) {
alert("Nastąpił wyjątek: " + wyjatek.toString());
} finally {
posprzątaj();
}
// ...
throw("nastąpił błąd");
Uwagi
edytujPrzypisy
edytuj- ↑ a b ECMAScript® 2021 Language Specification. 262.ecma-international.org. [dostęp 2021-08-07]. (ang.).
- ↑ ECMAScript® 2020 Language Specification
- ↑ From ECMAScript® 2020 Language Specification "ECMAScript was originally designed to be a Web scripting language, providing a mechanism to enliven Web pages in browsers and to perform server computation as part of a Web-based client-server architecture." https://262.ecma-international.org/11.0/#sec-overview
- ↑ From ECMAScript® 2020 Language Specification "ECMAScript usage has moved beyond simple scripting and it is now used for the full spectrum of programming tasks in many different environments and scales. As the usage of ECMAScript has expanded, so have the features and facilities it provides. ECMAScript is now a fully featured general-purpose programming language." https://262.ecma-international.org/11.0/#sec-overview
- ↑ From ECMAScript® 2020 Language Specification. "Some of the facilities of ECMAScript are similar to those used in other programming languages; in particular C, Java™, Self, and Scheme as described in: ISO/IEC 9899:1996, Programming Languages — C. Gosling, James, Bill Joy and Guy Steele. The Java™ Language Specification. Addison Wesley Publishing Co., 1996. Ungar, David, and Smith, Randall B. Self: The Power of Simplicity. OOPSLA '87 Conference Proceedings, pp. 227-241, Orlando, FL, October 1987. IEEE Standard for the Scheme Programming Language. IEEE Std 1178-1990." https://262.ecma-international.org/11.0/#sec-overview
- ↑ The TC39 process for ECMAScript features. 2ality.com.
- ↑ TC39-Royalty Free Technical Committee members [online], Ecma International [dostęp 2021-11-11] (ang.).
- ↑ ES5, ES6, ES2016, ES.Next: What's going on with JavaScript versioning?. benmccormick.org.
- ↑ JavaScript 2.0: Evolving a Language for Evolving Systems.
- ↑ ECMAScript 2015 Language Specification – ECMA-262 6th Edition [online], www.ecma-international.org [dostęp 2018-04-15] (ang.).
- ↑ a b Kagnax, ECMAScript 6 compatibility table [online], compat-table.github.io [dostęp 2024-01-14] .
- ↑ ECMAScript® 2016 Language Specification [online], www.ecma-international.org [dostęp 2018-04-15] .
- ↑ a b c d e f g h Kagnax, ECMAScript 2016+ compatibility table [online], compat-table.github.io [dostęp 2024-01-14] .
- ↑ ECMAScript® 2017 Language Specification [online], www.ecma-international.org [dostęp 2018-04-15] .
- ↑ ECMAScript® 2018 Language Specification [online], www.ecma-international.org [dostęp 2019-06-19] .
- ↑ Standard ECMA-262. www.ecma-international.org. [dostęp 2016-12-29].
- ↑ ECMAScript® 2020 Language Specification [online] .
- ↑ ECMAScript Language Specification
- ↑ Strict Mode – JavaScript MDN
- ↑ How to redefine JavaScript (NOT CSS) classes, in the console? [online], Stack Overflow, 2018 [dostęp 2023-12-09] (ang.).