ECMAScript 6: что принёс и что было после него

Содержание

О проверке кода. Примеры не запускались — в отличие от материалов по Node.js, где приводится фактический вывод. Говорим прямо, а не ставим бейдж «проверено» без проверки.

ES6 — самое значимое обновление в истории языка и одновременно источник вечной путаницы в названиях. Разберём и то, и другое.

Сначала про имя

ES6 и ES2015 — это один и тот же стандарт. Не две версии, не «шестая и пятнадцатая».

До 2015 года выпуски нумеровали по порядку: ES3, ES5. Шестой готовили почти десять лет, он получился огромным — и все привыкли звать его ES6. А в момент выхода комитет сменил схему: теперь стандарт выходит ежегодно и называется по году. Так ES6 официально стал ES2015.

Разговорное Официальное Год
ES5 ECMAScript 5 2009
ES6 ES2015 2015
ES7 ES2016 2016
ES2017 2017
ES2024 2024

После ES2015 разговорные номера умерли: «ES7» ещё говорят, «ES12» — уже нет. Подробнее про соотношение JavaScript и ECMAScript — в отдельном разборе.

Что принёс ES6

let и const вместо var

var x = 1;     // виден во всей функции, всплывает наверх
let y = 2;     // живёт только в своём блоке {}
const z = 3;   // то же, но переприсвоить нельзя

Разница не косметическая. var всплывает (hoisting) и виден во всей функции, из-за чего появлялась классическая ошибка:

// ❌ все три колбэка напечатают 3
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i));
}

// ✅ let создаёт новую переменную на каждой итерации
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i));   // 0, 1, 2
}

const не делает значение неизменяемым — он запрещает переприсваивать саму переменную. Объект под const менять можно:

const user = { name: 'Аня' };
user.name = 'Борис';    // ✅ работает
user = {};              // ❌ TypeError

Правило: по умолчанию const, let — если значение меняется, var — никогда.

Стрелочные функции: дело не в краткости

const double = (x) => x * 2;
[1, 2, 3].map((x) => x * 2);

Короче — приятный побочный эффект. Главное в стрелке — у неё нет своего this. Она берёт его из окружающего кода.

// ❌ обычная функция: свой this, здесь undefined
const timer = {
  seconds: 0,
  start() {
    setInterval(function () {
      this.seconds++;      // this — не timer!
    }, 1000);
  },
};

// ✅ стрелка: this взят снаружи, это timer
start() {
  setInterval(() => {
    this.seconds++;
  }, 1000);
}

До ES6 это лечили строкой var self = this; — её видно в любом коде тех лет.

Оборотная сторона: методом объекта стрелка быть не должна. this внутри неё будет не объектом, а тем, что снаружи.

Деструктуризация

const { name, age = 18 } = user;          // из объекта, со значением по умолчанию
const [first, ...rest] = [1, 2, 3];       // из массива
function greet({ name, city }) { }        // прямо в параметрах

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

Шаблонные строки

const msg = `Привет, ${name}! Тебе ${age} лет.`;
const html = `
  многострочный текст
  без \n и склейки
`;

⚠️ Важно: шаблонная строка не экранирует ничего. Собрать в ней HTML из данных пользователя и вставить через innerHTML — это XSS. Удобство подстановки к безопасности отношения не имеет.

Классы

class User {
  #secret = 'приватное поле';   // это уже не ES6, а ES2022
  constructor(name) { this.name = name; }
  greet() { return `Привет, ${this.name}`; }
}

Класс в JavaScript — синтаксический сахар над прототипами. Никакого нового механизма наследования не появилось: под капотом те же прототипы, просто запись человеческая.

Промисы

Самое важное для серверной разработки. Промисы в ES6 стали частью языка — до этого их приносили библиотеки вроде Bluebird и Q. Подробный разбор с замерами — в статье про промисы в Node.js.

Модули

import { readFile } from 'node:fs/promises';
export function helper() { }

import/export появились в ES6, но реально заработали намного позже: в браузерах — с 2018 года, в Node — ещё позже. Это редкий случай, когда стандарт сильно опередил реализацию.

Что было после ES6

Стандарт после 2015: маленькие ежегодные шаги
  1. 1 ES2015 (ES6)Огромный скачок: let, стрелки, классы, промисы, модули
  2. 2 ES2017async/await — то, ради чего промисы стали читаемыми
  3. 3 ES2020Promise.allSettled, опциональная цепочка ?., ??
  4. 4 ES2021—2022Promise.any, приватные поля #, at(), top-level await
  5. 5 ES2023—2024toSorted() без мутации, Object.groupBy()

Годовой цикл изменил отношение к версиям. Раньше ждали большой релиз и потом год переписывали код. Теперь каждый год приезжает пара методов, их подхватывают за минуту, и никто не считает номера.

Практический вывод: гоняться за версиями не нужно. Учить надо промисы и модули — это фундамент. Array.at() или Object.groupBy() осваиваются за минуту, когда понадобятся.

Нужен ли Babel

Короткий ответ: для ES6 — нет.

В 2017-м Babel стоял в каждом проекте: он превращал стрелки и let обратно в ES5, потому что Internet Explorer их не понимал. Это была обязательная часть сборки.

Сегодня все живые браузеры и все поддерживаемые версии Node понимают ES2020+ нативно. Транспиляция нужна ровно в двух случаях: очень свежие предложения стандарта или аудитория на реликтовых браузерах. Оба — редкость.

Что было на этой странице в 2017 году

Первая версия вышла 24 марта 2017 года и называлась «Новые возможности ES6». Слово «новые» — точный снимок момента: тогда ES6 действительно был новинкой, которую внедряли с осторожностью, а Babel был обязателен.

Что изменилось:

  • ES6 перестал быть новостью. Это просто язык. Отдельная статья про его возможности сегодня имеет смысл как исторический разбор, а не как «что нового».
  • Babel из обязательного стал редким. Вся инфраструктура вокруг «как использовать ES6 сегодня» испарилась вместе с задачей.
  • Появилось девять годовых выпусков после него — и ни один не сравним по масштабу. ES6 остался последним большим скачком в истории языка.

Мы оставили разбор возможностей — по этому запросу приходят те, кто разбирается в старом коде или готовится к собеседованию, — но добавили то, чего в 2017-м быть не могло: что случилось после.


Смежные темы: что такое JavaScript — язык, стандарт и среда; промисы и async/await — с замерами; массивы; уроки JavaScript.

Частые вопросы

ES6 и ES2015 — это разные стандарты?
Нет, одно и то же. После 2015 года комитет перешёл на годовую нумерацию, но за тем выпуском успело закрепиться имя «ES6». Формально правильно ES2015; в разговоре говорят и так, и так.
Нужен ли Babel в 2026?
Для ES6 — нет: все живые браузеры понимают его давно. Babel и подобные инструменты нужны для совсем свежих предложений или очень старой аудитории — то есть почти никогда.
Чем `let` отличается от `var`, если оба объявляют переменную?
Областью видимости. var виден во всей функции и всплывает наверх (hoisting), let живёт только в своём блоке {}. Отсюда классическая ошибка с var в цикле, где все колбэки получали последнее значение.
Стрелочная функция — это просто короткая запись?
Нет, и это главное про неё. У стрелки нет своего this: она берёт его из окружающего кода. Поэтому она отлично подходит для колбэков и не годится для методов объекта.
Что учить после ES6?
Ничего специально: обновления после 2015-го маленькие и точечные. Полезнее разобраться в промисах и модулях — это фундамент, а Array.at() или Object.groupBy() подхватываются за минуту.