ECMAScript

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacji, wyszukiwania

ECMAScript – ustandaryzowany przez ECMA obiektowy skryptowy języka programowania, którego najbardziej znane implementacje to JavaScript, JScript i ActionScript. Specyfikacja ta oznaczona jest jako ECMA-262 i ISO/IEC 16262.

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 model dokumentu lub specjalistyczne funkcje wejścia-wyjścia, obsługi GUI itp. nie wchodzą w skład specyfikacji ECMAScript, definiowane są przez inne standardy (W3C DOM) lub samych autorów konkretnych implementacji.

Zob. JavaScript by uzyskać więcej informacji na temat różnic między teoretyczną specyfikacją ECMAScript a jej faktycznymi implementacjami.

Podstawowe elementy składni wersji 3[edytuj | edytuj kod]

Komentarze[edytuj | edytuj kod]

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[edytuj | edytuj kod]

Zmienne są typowane dynamicznie. Definiowanie zmiennej polega na zwykłym przypisaniu jej wartości lub skorzystaniu z instrukcji var. Zmienne zdefiniowane poza funkcjami są dostępne w zasięgu globalnym (widoczne dla całego skryptu).

Tryb ścisły (strict mode) w ECMAScript 5 uniemożliwia przypisanie wartości do niezdefiniowanej zmiennej.

Instrukcje sterujące[edytuj | edytuj kod]

Podstawowe instrukcje są identyczne z instrukcjami znanymi z języków Java i C++.

Instrukcja if[edytuj | edytuj kod]

 if (warunki) {
     instrukcje;
 }
 else {
     instrukcje;
 }

Pętla while[edytuj | edytuj kod]

 while (warunki) {
     instrukcje;
 }

Pętla do...while[edytuj | edytuj kod]

 do {
     instrukcje
 } while (warunki);

Pętla for[edytuj | edytuj kod]

 for ([instrukcje-początkowe]; [warunki]; [instrukcje-krokowe]) {
     instrukcje-środkowe;
 }

Pętla for...in oraz for...of[edytuj | edytuj kod]

Pętla ta przechodzi przez wszystkie pola danego obiektu (w tym elementy tablicy):

 for (własność in obiekt) {
     instrukcje;
 }

Kolejność przechodzenia nie jest zdefiniowana w standardzie języka[1].

Pętla ta przechodzi przez wszystkie indeksy tablicy, pomijając właściwości nonenumerable:

 for (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 dwóch 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 najnowszym standardzie C++11.

Instrukcja switch[edytuj | edytuj kod]

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[edytuj | edytuj kod]

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. String), która od razu po wykorzystaniu jest usuwana. Podstawowym obiektem jest Object. Standard ECMA opisuje także obiekty Array (tablica), String (ciąg znaków), Number (liczba całkowita lub rzeczywista), Boolean (wartość logiczna), Function (funkcja ECMAScriptu), Date (data) i Math (operacje matematyczne).

Dostęp do pól i metod[edytuj | edytuj kod]

Obiekty ECMAScriptu są tablicami asocjacyjnymi. Dostęp do pól obiektów jest możliwy przy użyciu dwóch równoważnych notacji: obiekt.pole i 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 "with". Nie jest ona jednak dozwolona w trybie ścisłym ECMAScript 5[2]. Poniższe konstrukcje są równoważne:

obiekt.pole1=wartość;
obiekt.pole2=wartość;

i

with (obiekt)
{ pole1=wartość;
  pole2=wartość;
}

Definiowanie własnego obiektu[edytuj | edytuj kod]

Aby zdefiniować własny obiekt wystarczy utworzyć funkcję konstruktora:

// funkcja konstruktora
function MojObiekt(poleA, poleB) {
  this.poleA = poleA;
  this.poleB = poleB;
 
  function metoda1() {
    alert("mojObiekt::metoda1()");
  }
  this.metoda1 = metoda1;
 
  function metoda2() {
    alert("mojObiekt::metoda2()");
  }
  this.metoda2 = metoda2;
 
}

Dalsza część opisu mówi o "klasach", mimo że w przypadku ECMAScriptu pojęcie "klasy" jest nieformalne. "Klasa" oznacza tutaj zbiór obiektów utworzonych przy użyciu tego samego konstruktora.

Aby utworzyć instancję klasy MojObiekt, należy skorzystać z operatora new:

  var m = new MojObiekt(2, 3);

Podobnie jak w Javie, nowe obiekty w ECMAScripcie tworzone są na stercie. W przypadku kiedy do danego obiektu nie istnieje już żadna referencja mechanizm odśmiecania pamięci usuwa dany obiekt z pamięci.

Funkcje[edytuj | edytuj kod]

Funkcje w ECMAScripcie definiujemy przy użyciu słowa kluczowego function, a jej argumenty podajemy w nawiasach:

function dodajDwieLiczby(a, b) {
  return a+b;
}

Funkcje są jednocześnie obiektami typu Function. Obiekt ten ma konstruktor przyjmujący jako argument ciąg znaków, powyższą funkcję można więc także zdefiniować w sposób następujący:

dodajDwieLiczby = new Function("a", "b", "return a+b;");

Ostatni argument Function() jest treścią kodu funkcji, pozostałe to nazwy parametrów. Ten sposób tworzenia funkcji jest jednak mało wydajny.

Podobny sposób na deklarowanie funkcji:

var dodajDwieLiczby = function(a, b) {
  return a+b;
}

W przeciwieństwie do Javy ECMAScript pozwala także operować na referencjach do funkcji:

  function dodaj(a,b) {
    alert(a+b);
  }
 
  function odejmij(a,b) {
    alert(a-b);
  }
 
  var g = dodaj;
 
  g(7,3); // wyświetla "10"
 
  g = odejmij;
 
  g(7,3); // wyświetla "4"

Dziedziczenie[edytuj | edytuj kod]

W implementacjach ECMAScript V3 dziedziczenie realizowane jest przez prototypy. Jeśli chcemy utworzyć klasę Pochodna dziedziczącą po klasie Bazowa, ustawiamy pole Pochodna.prototype na nową instancję klasy Bazowa:

  function Bazowa() {
    this.metodaA = function() {
      alert("Bazowa::A()");
    }
    this.metodaB = function() {
      alert("Bazowa::B()");
    }
  }
 
  function Pochodna() {
    // metodaB przeciąża odpowiednią metodę z klasy Bazowa:
    this.metodaB = function () {
      alert("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()"

Istnieją inne sposoby na uzyskanie dziedziczenia w ECMAScripcie. Osoby przyzwyczajone do Javy lub C++ mogą zmodyfikować prototyp obiektu Object w następujący sposób:

  Object.prototype.extends = function (supClass) {
    tempObj = new supClass();
    for (property in tempObj) {
	this[property] = tempObj[property];       
    } 
  };

by później w funkcjach konstruktora korzystać z metody extends(), rozwiązującej szybko problem dziedziczenia. Oto przykład:

  function Bazowa() {
 
    this.value = 5;
 
    this.metoda1 = function () {
	alert("Bazowa::metoda1() " + this.value);
    }
 
    this.metoda2 = function () {
	alert("Bazowa::metoda2()");
    }
 
  }
 
  function Pochodna() {
    this.extends(Bazowa);
 
    this.metoda1 = function () {
	alert("Pochodna::metoda1() " + this.value);
    }
  }

Ważne tylko, żeby extends() wywoływać jako pierwszą instrukcję w konstruktorze.

Obsługa wyjątków[edytuj | edytuj kod]

Do obsługi wyjątków w ECMAScripcie wykorzystywana jest "klasa" Error, odpowiadająca znanej z Javy klasie Exception.

Aby wyrzucić nowy wyjątek, należy skorzystać z instrukcji throw:

  function zrobCos() {
    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 {
    zrobCos();
  } catch (wyjatek) {
    alert("Nastąpił wyjątek: " + wyjatek.toString());
  } finally {
    posprzataj();
  }
  ...
  throw("nastapil blad");

Linki zewnętrzne[edytuj | edytuj kod]

Przypisy