Babel.js — ES6 уже сейчас

В последние годы JavaScript стремительно проникает во все области разработки программного обеспечения. Разработчикам хочется уже сейчас использовать современный стандарт ECMA Script 6 (ES6), но до полной поддержки в браузерах еще далеко. На помощь приходит Babel.js.

Babel реализует поддержку новых фич JS при помощи синтаксической трансформации. Это позволяет уже сейчас использовать новый стандарт в браузере. Для начала нужно добавить Babel в свой проект:

$ npm install --save-dev babel-cli

Теперь создадим файл с некоторыми примерами нового синтаксиса ES6:

var evens = [0, 1, 2, 3, 4];

var odds = evens.map(v => v + 1);
var nums = evens.map((v, i) => v + i);

console.log(odds, nums);

Преобразуем этот код при помощи Babel следующей командой

$ ./node_modules/.bin/babel src -d lib

Первый аргумент src — это директория с js-файлами, которые нужно обработать, а ключ d задает конечный путь, по которому будут помещены итоговые файлы.

Теперь вкратце рассмотрим некоторые новые возможности стандарта ES6.

Классы

Ключевое слово class является простым синтаксическим сахаром для стандартного прототипного наследования. Теперь определение классов будет иметь единый и последовательный синтаксис. Classes support prototype-based inheritance, super calls, instance and static methods and constructors. Классы поддерживают прототипное наследование, обращения к функциям родительского класса (при помощи super), конструкторы, статические и простые методы. Определение простого класса выглядит так:

class Cat {
	constructor(a, b) {
		console.log(a, b)
	}

	meow (say) {
		console.log("Cat say", say);
	}
}

var Tom = new Cat(1, 2);
Tom.meow("Meow");

Типы переменных let и const

В ES6 предусмотрены новые способы объявления переменных: через let и const вместо var.

let a = 1;
const PI = 3.1415;

Переменная, объявленная с модификатором const, становится константой. Ее нельзя изменять в процессе выполнения программы. Переменная с модификатором let, видна только в рамках блока {…}, в котором объявлена. То есть две переменные с одинаковым именем определенные в разных блоках — это независимые переменные. Изменение одной никак не повлияет на другую. Это ключевое отличие let от var.

Аргументы по умолчанию и оставшиеся параметры

Теперь есть возможность задавать функции аргументы со значением по-умолчанию. В некоторых случаях может быть полезно вместо стандартного undefined для пропущенных аргументов задавать другое значение. Синтаксис rest-параметров позволяет функции принимать неограниченное количество параметров в виде массива. Это дает возможность избежать манипуляций с arguments.

function getDiscount(price, discount = 10) {
	console.log("Get discount for price", price * ( discount / 100));
}

getDiscount(100);
getDiscount(100, 5);

function addToCart(price, ...products) {
	console.log(price, ...products);
}

addToCart(1000, "milk", "apple", "banana");

Генераторы и итераторы

Генераторы – новый вид функций в современном JavaScript. Они отличаются от обычных тем, что могут приостанавливать своё выполнение, возвращать промежуточный результат и далее продолжать производить его позже, в произвольный момент времени. Для объявление функции-генератора используется синтаксис function*. Выглядит это так.

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

При вызове такой функции она возвращает специальный объект, который и называют генератор. Ключевую роль здесь играет метод next(), каждый вызов которого возобновляет работу функции.

'use strict';

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();

let one = generator.next();

alert(JSON.stringify(one)); // {value: 1, done: false}

Следующий вызов generator.next() возобновит выполнение и вернёт результат следующего yield:

let two = generator.next();

alert(JSON.stringify(two)); // {value: 2, done: false}

Новые значения будут генерироваться по тех пор, пока выполнение не дойдет до return. Последним значением генераторы будет являться {value: 3, done: true}.

Promise

Promise (их обычно называют «промисы») – предоставляют удобный способ организации асинхронного кода. Их удобно использовать для того, чтобы избежать «ада коллбэков» — когда в коде присутствует множество вложенных обратных вызовов. Promise – это специальный объект, который содержит своё состояние. Вначале pending («ожидание»), затем – fulfilled («выполнено успешно») или rejected («выполнено с ошибкой»). На promise можно навешивать коллбэки двух типов: на успех и на неудачу.


var promise = new Promise(function(resolve, reject) {
  // Эта функция будет вызвана автоматически

  // В ней можно делать любые асинхронные операции,
  // А когда они завершатся — нужно вызвать одно из:
  // resolve(результат) при успешном выполнении
  // reject(ошибка) при ошибке
})

Подробнее о новых возможностях ES6 можно узнать по ссылке.