Loading AI tools
język programowania Z Wikipedii, wolnej encyklopedii
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].
Zaraz 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[uwaga 1] |
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[uwaga 2] |
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]. |
Komentarze 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 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).
Podstawowe instrukcje są identyczne z instrukcjami znanymi z języków Java i C++.
if
if (warunki) {
instrukcje;
} else {
instrukcje;
}
while
while (warunki) {
instrukcje;
}
do...while
do {
instrukcje
} while (warunki);
for
for ([instrukcje - początkowe];[warunki];[instrukcje - krokowe]) {
instrukcje - środkowe;
}
for...in
oraz for...of
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:
for_each
z bibliotekami boost::bind oraz boost::lambdaswitch
Analogicznie jak w C, C++, PHP i Javie.
switch (wyrażenie) {
case wartość1:
instrukcje;
break;
case wartość2:
instrukcje;
break;
default:
instrukcje;
break;
}
W 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
Obiekty 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ść;
}
Aby 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 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;
W 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()”
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
Do 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");
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.