ECMAScript 5.1

ECMAScript 5.1 (ES5.1) je poslední verzí ECMAScriptu, standardu, na kterém je postaven JavaScript. Podobně jako u HTML5 je i ES5 standardizací existujících implementací a rozšíření jazyka. Jednou z nich je například strict mode, o němž jsme už psali. V článku si představíme některé další novinky verze 5.1.

Překlad článku Introducing ECMAScript 5.1 (autor: Mike Taylor) z webu Dev.Opera. Překlad vychází s laskavým svolením Opera Software.

Úplný seznam novinek naleznete v přílohách D a E v oficiální specifikaci ECMAScriptu (PDF) na webu http://www.ec­mascript.org/;  v HTML podobě jej najdete na stránkách Michael[tm] Smith’s unofficial annotated HTML version.

Podpora ES5.1 v prohlí­žečích

S vydáním Opery 11.60 je ES5 podporován ve všech pěti hlavních prohlížečích. Pokud nebude řečeno jinak, budou všechny dále zmiňované vlastnosti dostupné v těchto verzích (a vyšších):

  • Opera 11.60
  • Internet Explorer 9*
  • Firefox 4
  • Safari 5.1**
  • Chrome 13

* IE9 zatím nepodporuje strict mode, až ve verzi IE10.

** V Safari 5.1 stále není podpora pro Function.prototype.bind, ačkoli před nedávnem byla přidána do Webkitu .

Stav podpory ve starších prohlížečích naleznete na stránce ECMAScript 5 compatibility table od Jurije Zajceva (Juriy Zaytsev).

Strict Mode v ES5

Strict mode (viz ECMAScript Strict mode ve Firefoxu 4) je způsob, jakým se vývojář může přihlásit k restriktivnější verzi jazyka, která přináší vyšší bezpečnost a spolehlivost. Strict mode je nastaven přidáním direktivy "use
strict";
na začátek souboru nebo funkce. Protože je tato direktiva prostý řetězec, bude bez problémů staršími prohlížeči ignorována.

"use strict";
function strict(){
  "use strict";
  //...
}

function sloppy(){
  eval("window.foo = 'bar'");
}

Mnoho věcí, které v normálním JavaScriptu způsobí nepředvídatelné chybné chování, způsobí ve strict mode výjimku, kupříkladu:

  • Přiřazení do nedeklarované proměnné vyhodí ReferenceError (v prostém JS vytvoří globální proměnnou).
  • Vícenásobné přiřazení do stejně pojmenované vlastnosti v objektovém zápisu vyvolá  SyntaxError.
  • Byla odstraněna konstrukce with. Její použití vyvolá  SyntaxError.

Pěkné shrnutí těchto rozdílů naleznete v článku na MDSN.

JSON

ES5 zavádí globální objekt JSON, který slouží k serializaci ( JSON.stringify) a deserializaci ( JSON.parse) objektů do/z formátu JSON.

U starších prohlížečů lze použít polyfill skript json2.js od Douglase Crockforda, který poskytuje stejnou funkčnost (samosebou nejprve otestuje nativní podporu).

JSON.parse(text [, reviver])

JSON.parse bere řetězec (ve formátu JSON) a vrací hodnotu. Volitelný parametr reviver je funkce s dvěma argumenty, key a value, která je provedena nad výsledky, což je umožňuje filtrovat a měnit před tím, než jsou vráceny.

>> var result = JSON.parse('{"a": 1, "b": "2"}');
Object

>> result.b
"2"

Pokud se chceme ujistit, že výsledkem bude celé číslo (nikoli řetězec), použijeme tuto funkci.

var result = JSON.parse('{"a": 1, "b": "2"}', function(key, value){
  if (typeof value == 'string'){
    return parseInt(value);
  } else {
    return value;
  }
})

>> result.b
2

JSON.stringify(value [, replacer [, space]])

JSON.stringify bere hodnotu a převádí ji na řetězec ve formátu JSON. V nejjednodušší podobě přebírá jednu hodnotu a vrací řetězec.

>>> var mike = JSON.stringify({mike: "taylor"})
undefined

>> mike
'{"mike": "taylor"}'

>> typeof mike
"string"

Když potřebujeme změnit způsob, jakým je hodnota převedena na řetězec, nebo filtrovat data, můžeme předat funkci replacer. Kupříkladu pokud chceme vynechat hodnotu 13, můžeme to provést takto:

var nums = {
  "first": 7,
  "second": 14,
  "third": 13
}

var luckyNums = JSON.stringify(nums, function(key, value){
  if (value == 13) {
    return undefined;
  } else {
    return value;
  }
});

>> luckyNums
'{"first": 7, "second": 14}'

Pokud funkce replacer vrátí hodnotu  undefined, nebude tento klíč ve výsledném JSON zahrnut. Třetím argumentem je počet mezer, kterým se má odsadit zanoření (kvůli lepší čitelnosti výsledného textu), nebo řetězec, který je přidán jako výplň odsazování. Hodnoty větší než 10 jsou převedeny na 10, řetězec delší než 10 znaků je oříznut a je použito pouze prvních deset znaků.

var luckyNums = JSON.stringify(nums, function(key, value) {
  if (value == 13) {
    return undefined;
  } else {
    return value;
  }
}, 2);

>> luckyNums
'{
  "first":7,
  "second":14
}'

Rozšíření Object

Ke konstruktoru  Object byly přidány následující metody:

  • Object.getPrototypeOf
  • Object.getOwnPropertyDescriptor
  • Object.getOwnPropertyNames
  • Object.create
  • Object.defineProperty
  • Object.defineProperties
  • Object.seal
  • Object.freeze
  • Object.preventExtensions
  • Object.isSealed
  • Object.isFrozen
  • Object.isExtensible
  • Object.keys

Jednou z výhod je lepší řízení práce s vlastnostmi objektu, např. určení, které lze měnit, procházet, mazat apod. Tyto možnosti se nastavují pomocí tzv. property deskriptorů. Kupříkladu:

var cat = {};

Object.defineProperty(cat, "name", {
  value: "Maru",
  writable: false,
  enumerable: true,
  configurable: false
});

Object.defineProperty(cat, "skill", {
  value: "exploring boxes",
  writable: true,
  enumerable: true,
  configurable: true
});

U našeho objektu cat nelze měnit vlastnost name, ale objeví se při procházení smyčkou  for-in (enumerable). Kromě jiného je Maru dobrá v prozkoumávání krabiček, ale tato schopnost může být v budoucnu změněná, tak má vlastnost skill ponechané příznaky writableconfigurable.

V některém z dalších článků se k těmto vlastnostem vrátíme.

Vylepšení polí

K prototypu Array byly přidány následující možnosti:

  • Array.prototype.indexOf
  • Array.prototype.lastIndexOf
  • Array.prototype.every
  • Array.prototype.some
  • Array.prototype.forEach
  • Array.prototype.map
  • Array.prototype.filter
  • Array.prototype.reduce
  • Array.prototype.reduceRight

Dmitrij Šošnikov (Dmitry Soshnikov) napsal podrobný článek o těchto rozšířeních polí v ES5.

Jedna metoda, kterou Dmitrij v článku nezmínil, je Array.isArray, která je přidána přímo ke konstruktoru, nikoli k prototypu.  Array.isArray dělá to, co od něj očekáváme – je to metoda, která vrátí  true nebo false podle toho, jestli vnitřní vlastnost [[Class]] je rovna „Array“.

Array.isArray("NO U")
>> false

Array.isArray(["NO", "U"])
>> true

V ES3 byl jediný použitelný způsob, jak určit, zda je hodnota pole nebo ne, takzvaný „the Miller Device“, neboli porovnání interní vlastnosti [[Class]] s tou, kterou má pole.

Object.prototype.toString.apply(value) === '[object Array]'

Function.prototype.bind(thisArg [, arg1 [, arg2, …]])

Function.prototype.bind vrací novou funkci, u níž je hodnota this nastavena podle argumentu thisArg. To umožňuje vykonat funkci v kontextu jiného objektu

function locate(){
  console.log(this.location);
}

function Maru(location){
  this.location = location;
}

var kitty = new Maru("cardboard box");

var locateMaru = locate.bind(kitty);

locateMaru();

V tomto příkladu voláme funkci location v kontextu objektu Maru. Protože locate je vlastností globálního objektu, je v něm this rovno právě globálnímu objektu ( window). V našem případě hledáme kočku, nikoli objekt Location, takže si vytvoříme novou funkci locateMaru, kde je hodnota this svázána s  kitty.

Další zdroje informací

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Komentáře: 12

Přehled komentářů

dmkil vdaka
alancox Re: vdaka
Pavel Křivánek mělká kopie
Aichi Re: mělká kopie
Pavel Křivánek Re: mělká kopie
asdasd Re: mělká kopie
langpa Re: mělká kopie
asdasd Re: mělká kopie
BS-Harou Re: mělká kopie
Pavel Křivánek Re: mělká kopie
Pavel Křivánek Re: mělká kopie
asdasd Re: mělká kopie
Zdroj: https://www.zdrojak.cz/?p=3586