ECMAScript 5 (2009)

ECMAScript 5 также известен как ES5 и ECMAScript 2009.

В этой главе мы рассмотрим некоторые новые особенности ES5.

В ES5 был добавлен следующий функционал:

  • Директива "use strict"
  • String.trim()
  • Array.isArray()
  • Array.forEach()
  • Array.map()
  • Array.filter()
  • Array.reduce()
  • Array.reduceRight()
  • Array.every()
  • Array.some()
  • Array.indexOf()
  • Array.lastIndexOf()
  • JSON.parse()
  • JSON.stringify()
  • Date.now()
  • Геттеры и сеттеры свойств
  • Новые методы объектов для работы со свойствами

Также, в ECMAScript 5 были внесены изменения синтаксиса:

  • Доступ к символам в стоковых переменных при помощи [ ]
  • Конечная запятая в литералах массивов и объектов
  • Многострочные строковые литералы
  • Зарезервированные слова как имена свойств

Директива "use strict"

Директива "use strict"; указывает, что код JavaScript должен выполняться в "строгом режиме".

В строгом режиме вы не можете, например, использовать не декларированные переменные.

Вы можете использовать строгий режим во всех своих программах. Она позволяет писать более чистый код, например, предотвращая использование недекларированных переменных.

Директива "use strict" — это просто строковое выражение. Старые браузеры не сгенерируют никакой ошибки, если не поймут ее.

Подробнее об этой директиве см. главу Строгий режим Javascript.

String.trim()

Метод String.trim() удаляет пробельные символы в начале и в конце строки.


var str = "       Hello World!        ";
alert(str.trim()); 

Array.isArray()

Метод isArray() проверяет, является ли объект массивом.


function myFunction() {
  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  var x = document.getElementById("demo");
  x.innerHTML = Array.isArray(fruits);
} 

Подробнее о массивах см. главу Массивы (объект Array)

Array.forEach()

Метод forEach() единожды вызывает функцию (функцию обратного вызова) для каждого элемента массива.


var txt = "";
var numbers = [45, 4, 9, 16, 25];
numbers.forEach(myFunction);

function myFunction(value, index, array) {
   txt = txt + value + "<br>"; 
} 

Array.map()

Метод map() создает новый массив, предварительно выполнив функцию обратного вызова с каждым элементом исходного массива.

В следующем примере создается новый массив, значениями элементов которого будут значения элементов исходного массива умноженные на 2:


var numbers1 = [45, 4, 9, 16, 25];
var numbers2 = numbers1.map(myFunction);

function myFunction(value) {
   return value * 2;
} 

Array.filter()

Метод filter() создает новый массив с элементами исходного массива, прошедшими заданную проверку.

В следующем примере создается новый массив из элементов исходного массива значения, которых больше 18:


var numbers = [45, 4, 9, 16, 25];
var over18 =  numbers.filter(myFunction);

function myFunction(value) {
  return value > 18;
} 

Array.reduce()

Метод reduce() обрабатывает элементы массива слева направо.

В следующем примере вычисляется сумма всех чисел в массиве:


var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduce(myFunction);

function myFunction(total, value) {
  return total + value;
} 

Array.reduceRight()

Метод reduceRight() обрабатывает элементы массива справа налево.

В следующем примере также вычисляется сумма всех чисел в массиве:


var numbers1 = [45, 4, 9, 16, 25];
var sum = numbers1.reduceRight(myFunction);

function myFunction(total, value) {
  return total + value;
} 

Array.every()

В следующем примере проверяется, больше ли 18 значения всех элементов массива:


var numbers = [45, 4, 9, 16, 25];
var allOver18 =  numbers.every(myFunction);

function myFunction(value) {
  return  value > 18;
} 

Array.some()

В следующем примере проверяется, есть ли в массиве хотя бы один элемент со значением больше 18:


var numbers = [45, 4, 9, 16, 25];
var someOver18 = numbers.some(myFunction);

function myFunction(value) {
   return  value > 18;
} 

Array.indexOf()

Ищет в массиве элемент с заданным значение и возвращает его позицию:


var fruits = ["Apple", "Orange", "Banana", "Mango"];
var a = fruits.indexOf("Apple"); 

Array.lastIndexOf()

Метод Array.lastIndexOf() работает также как метод Array.indexOf(), только поиск начинается с конца массива.


var fruits = ["Banana", "Orange", "Apple", "Mango"];
var a = fruits.indexOf("Apple"); 

Подробнее о методах для работы с элементами массива см. главу Перебирающие методы массива.

JSON.parse()

Обычно JSON используется для получения данных с сервера.

Представьте, что вы получили с сервера такую текстовую строку:


'{"name":"John", "age":30, "city":"New York"}' 

Функция JSON.parse() используется, чтобы конвертировать такую текстовую строку в объект JavaScript:


var obj = JSON.parse('{"name":"John", "age":30, "city":"New York"}'); 

JSON.stringify()

Обычно JSON используется для отправки данных на сервер. При этом отправляемые данные должны быть в виде текстовой строки.

Представьте, что у вас есть такой объект JavaScript:


var obj = {"name":"John", "age":30, "city":"New York"}; 

При помощи функции JSON.stringify() мы конвертируем этот объект в текстовую строку:


var myJSON = JSON.stringify(obj); 

Теперь в переменной myJSON находится строка, отформатированная по правилам JSON, которую можно отправить на сервер.


var obj = {"name":"John", "age":30, "city":"New York"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON; 

Date.now()

Метод Date.now() возвращает количество миллисекунд, прошедших с нулевой даты (1 января, 1970 00:00:00 UTC).


var timInMSs = Date.now(); 

Метод Date.now() возвращает тот же результат, что и метод getTime() выполненный с объектом Date.

Подробнее об объекте Date см. главу Дата (Объект Date).

Геттеры и сеттеры свойств

ES5 позволяет определять методы объектов в виде геттеров и сеттеров свойств.

В следующем примере создается геттер с именем fullName:


// Создаем объект
var person = {
  firstName: "John",
  lastName : "Doe",
  get fullName() {
    return this.firstName + " " + this.lastName;
  }
};

// Выводим данные при помощи геттера
document.getElementById("demo").innerHTML =  person.fullName; 

В следующем примере создается геттер и сеттер для свойства language:


var person = {
  firstName: "John",
  lastName : "Doe",
  language : "NO",
  get lang() {
    return this.language;
  },
  set lang(value) {
    this.language = value;
  }
};

// Задаем значение свойству объекта при помощи сеттера
person.lang = "en";

// Выводим данные при помощи геттера
document.getElementById("demo").innerHTML =  person.lang;

В следующем примере используется сеттер, чтобы гарантировать, что новое значение свойства language всегда будет записано большими буквами:


var person = {
  firstName: "John",
  lastName : "Doe",
  language : "NO",
  set lang(value) {
    this.language = value.toUpperCase();
  }
};

// Задаем значение свойству объекта при помощи сеттера
person.lang = "en";

// Выводим данные
document.getElementById("demo").innerHTML =  person.language;

Новые методы объектов для работы со свойствами

В ES5 появился новый метод объекта Object — Object.defineProperty().

Он позволяет определять свойство объекта и/или изменять значение свойства и/или его метаданные.


// Создаем объект
var person = {
  firstName: "John",
  lastName : "Doe",
  language : "NO", 
};

// Изменяем свойство
Object.defineProperty(person, "language", {
  value: "EN",
  writable : true,
  enumerable : true,
  configurable : true
});

// Перечисляем свойства
var txt = "";
for (var x in person) {
    txt += person[x] + "<br>";
}
document.getElementById("demo").innerHTML =  txt;

Код следующего примера такой же как в предыдущем, за исключением того, что здесь свойство language закрывается от перечисления:


// Создаем объект
var person = {
  firstName: "John",
  lastName : "Doe",
  language : "NO", 
};

// Изменяем свойство
Object.defineProperty(person, "language", {
  value: "EN",
  writable : true,
  enumerable : false,
  configurable : true
});

// Перечисляем свойства
var txt = "";
for (var x in person) {
    txt += person[x] + "<br>";
}
document.getElementById("demo").innerHTML =  txt;

В следующем примере создается геттер и сеттер, чтобы гарантировать, что новое значение свойства language всегда будет записано большими буквами:


// Создаем объект
var person = {
  firstName: "John",
  lastName : "Doe",
  language : "NO"
};

// Изменяем свойство
Object.defineProperty(person, "language", {
  get : function() { return  language },
  set : function(value) { language = value.toUpperCase()}
});

// Устанавливаем новое значение
person.language = "en";

// Выводим значение свойства language
 document.getElementById("demo").innerHTML = person.language; 

В ECMAScript 5 было добавлено много новых методов объекта Object:


// Добавить или изменить свойство объекта
Object.defineProperty(объект, свойство, описатель)

// Добавить или изменить несколько свойств объекта
Object.defineProperties(объект, описатель)

// Доступ к свойствам
Object.getOwnPropertyDescriptor(объект, свойство)

// Возвращает все свойства в виде массива
Object.getOwnPropertyNames(объект)

// Возвращает перечисляемые свойства в виде массива
Object.keys(объект)

// Доступ к прототипу
Object.getPrototypeOf(объект)

// Запрещает добавление свойств объекту
Object.preventExtensions(объект)
// Возвращает true, если объекту разрешено добавлять свойства
Object.isExtensible(объект)

// Запрещает изменять свойств объекта (не значения)
Object.seal(объект)
// Возвращает true, если объект "запечатан"
Object.isSealed(объект)

// Запрещает любые изменения объекта
Object.freeze(объект)
// Возвращает true, если объект "заморожен"
Object.isFrozen(объект) 

Посимвольный доступ в строках

Метод charAt() возвращает символ строки, находящийся в заданной позиции (индексе):


var str = "HELLO WORLD";
str.charAt(0);            // возвращает H

ECMAScript 5 позволяет обращаться к каждому символу строки:


var str = "HELLO WORLD";
str[0];                   // возвращает H 

Иногда посимвольный доступ к строке может оказаться немного непредсказуемым.

Конечная запятая

ECMAScript 5 позволяет использовать конечную запятую в определениях объектов и массивов:


// Пример объекта
person = {
  firstName: "John",
  lastName: " Doe",
  age: 46,
}

// Пример массива
points = [
  1,
  5,
  10,
  25,
  40,
  100,
]; 

ВНИМАНИЕ !!! В Internet Explorer 8 конечная запятая в определениях объектов и массивов приведет к краху.

В JSON запрещены конечные запятые.

Объекты JSON:


// Можно
var person = '{"firstName":"John", "lastName":"Doe", "age":46}'
JSON.parse(person)

// Нельзя
var person = '{"firstName":"John", "lastName":"Doe", "age":46,}'
JSON.parse(person)

Массивы JSON:


// Можно
points = [40, 100, 1, 5, 25, 10]

// Нельзя
points =  [40, 100, 1, 5, 25, 10,]

Многострочные строковые значения

ECMAScript 5 позволяет для разбивки строковых литералов на несколько строк использовать символ \ (обратный слэш):


"Hello \
Dolly!"; 

Использование символа \ для разбивки строкового значения не имеет универсальной поддержки. Старые браузеры могут по разному интерпретировать пробелы вокруг слэша. Некоторые старые браузеры не позволяют использование пробелов после символа \.

Более безопасный способ разбить строковый литерал — это использование строкового сложения:


"Hello " + 
"Dolly!"; 

Зарезервированные слова как имена свойств

ECMAScript 5 позволяет использование зарезервированных слов в качестве имен свойств:


var obj = {name: "John", new: "yes"}