ES6: что нового в новой версии JavaScript

13.01.2016

Вероятно, вы уже слышали об ECMAScript 6, или ES6. Это новая версия языка JavaScript, в которой было реализовано множество полезных особенностей. Далее мы рассмотрим некотрые из этих особенностей.

Переменные

let

Для объявления переменной мы привыкли использовать ключевое слово var. Теперь так же можно использовать ключевое слово let. Они отличаются областью видимости объявляемой переменной. Переменная, объявленная с помощью var видна в пределах всей функции, переменная, объявленная с помощью let — только в пределах блока.


if (true) {
   let x = 1;
}
console.log(x); // undefined

Это делает код чище, если переменная используется только в блоке — она доступна только в этом блоке. Особенно это актуально для цикла for.


for (let i = 0, l = list.length; i < l; i++) {
    // do something with list[i]
}
console.log(i); // undefined

const

Ключевое слово const также позволяет создать переменную уровня блока, но такая переменная обязательно должна иметь значение и не доступна для перезаписи.


const MY_CONSTANT = 1;
MY_CONSTANT = 2 // Error
const SOME_CONST; // Error

Но если значением переменной является массив или объект — отдельные свойства или элементы массива можно редактировать.

Стрелочные функции (Arrow Functions)

Использование стрелочных функций в определенных случаях делает код более красивым и лаконичным. В примере ниже один и тот же код оформлен в виде стрелочной функции и обычной функции ES5:


let books = [{title: 'X', price: 10}, {title: 'Y', price: 15}];

let titles = books.map( item => item.title );

// ES5 equivalent:
var titles = books.map(function(item) {
    return item.title;
});

В синтаксисе стрелочной функции нет ключевого слова function, сначала указывается список параметров, если необходимо, затем «толстая стрелка» и далее тело функции. Если параметров нет, указываются пустые круглые скобки:


// No arguments
books.map( () => 1 ); // [1, 1]

// Multiple arguments
[1,2].map( (n, index) => n * index ); // [0, 2]

Если тело функции содержит больше одного выражения, его необходимо поместить в фигурные скобки.


let result = [1, 2, 3, 4, 5].map(n => {
    n = n % 3;
    return n;
});

Стрелочные функции отличаются от обычных не только более коротким синтаксисом. Стрелочная функуция наследует значения this и arguments от окружающего контекста. Это означает, что вам не нужно писать уродливое var that = this, контекст выполнения будет правильным. Ниже пример на ES6 или аналог на ES5:


let book = {
    title: 'X',
    sellers: ['A', 'B'],
    printSellers() {
        this.sellers.forEach(seller => console.log(seller + ' sells ' + this.title));
    }
}

// ES5 equivalent:
var book = {
    title: 'X',
    sellers: ['A', 'B'],
    printSellers: function() {
        var that = this;
        this.sellers.forEach(function(seller) {
            console.log(seller + ' sells ' + that.title)
        })
    }
}

Строки

Методы

Несколько полезных методов были добавлены к пототипу String.


'my string'.startsWith('my'); //true
'my string'.endsWith('my'); // false
'my string'.includes('str'); // true
'my '.repeat(3); // 'my my my '

Литерал шаблона (template literal)

Литерал шаблона позволяет использовать переменные внутри строки, заключенные в символы ${...}, например:


let name = 'John',
   apples = 5,
   pears = 7,
   bananas = function() { return 3; }

console.log(`This is ${name}.`);

console.log(`He carries ${apples} apples, ${pears} pears, and ${bananas()} bananas.`);

// ES5 equivalent:
console.log('He carries ' + apples + ' apples, ' + pears + ' pears, and ' + bananas() +' bananas.');

Литерал шаблона также можно использовать для многострочных строк (не забывайте, что пробел также является частью строки):


let x = `1...
2...
3 lines long!`; // Yay

// ES5 equivalents:
var x = "1...\n" + 
"2...\n" +
"3 lines long!";

var x = "1...\n2...\n3 lines long!";

Массивы

Массивы также получили несколько полезных методов.

Метод Array.from создает массивы из объектов, похожих на массивы или итерируемых объектов. Примерами объектов, похожих на массив, являются:

  • переменная arguments внутри функции;
  • коллекция nodeList, возвращаемая document.getElementsByTagName();
  • новые структуры данных Map и Set.

let itemElements = document.querySelectorAll('.items');
let items = Array.from(itemElements);
items.forEach(function(element) {
    console.log(element.nodeType)
});

// A workaround often used in ES5:
let items = Array.prototype.slice.call(itemElements);

В примере выше метод forEach доступен в коллекции itemElements.

Интересной особенностью метода Array.from является второй аргумент mapFunction. Он позволяет преобразовать каждый элемент при создании массива:


let navElements = document.querySelectorAll('nav li');
let navTitles = Array.from(navElements, el => el.textContent);

Также теперь у нас есть метод Array.of, функционал которого очень похож на конструктор массива. Он отличается для случая с одним параметром.


let x = new Array(3); // [undefined, undefined, undefined]
let y = Array.of(8); // [8]
let z = [1, 2, 3]; // Array literal

Несколько новых методов были добавлены прототипу Array.

  • find возвращает первый элемент, для которго переданная функция обратного вызова вернет true.
  • findIndex возвращает индекс первого элемента, для которго переданная функция обратного вызова вернет true.
  • fill «перезаписывает» элементы массива заданным значением.

[5, 1, 10, 8].find(n => n === 10) // 10

[5, 1, 10, 8].findIndex(n => n === 10) // 2

[0, 0, 0].fill(7) // [7, 7, 7]
[0, 0, 0, 0, 0].fill(7, 1, 3) // [0, 7, 7, 7, 0]
Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться