← Назад к курсу

Учебное пособие по JavaScript ES6+

Введение

ECMAScript 2015 (также известный как ES6) — это крупное обновление языка JavaScript, выпущенное в 2015 году. Оно добавило множество новых синтаксических конструкций и возможностей, которые сделали код более чистым, выразительным и удобным для поддержки. Последующие версии (ES2016, ES2017, …, ES2023) продолжают улучшать язык.

В этом пособии мы рассмотрим самые важные и полезные возможности ES6+, которые должен знать каждый современный разработчик.


1. Объявление переменных: let и const

Раньше для объявления переменных использовался только var. В ES6 появились let и const, которые решают проблемы области видимости и неизменяемости.

Ключевое слово Область видимости Переприсваивание Повторное объявление в той же области
var функциональная да да (проблематично)
let блочная { } да нет
const блочная { } нет нет
// let — значение можно менять
let count = 0;
count = 1; // OK

// const — значение нельзя переназначить
const PI = 3.14;
PI = 3.1415; // Ошибка!

// const с объектами: нельзя заменить объект, но можно менять его свойства
const user = { name: 'Иван' };
user.name = 'Петр'; // OK
user = {};          // Ошибка!

Важно: let и const не подвержены «поднятию» (hoisting) в том же смысле, что и var, и находятся во «временной мёртвой зоне» до момента объявления.


2. Стрелочные функции

Стрелочные функции предоставляют краткий синтаксис и, что важнее, не имеют собственного this (берут this из внешнего лексического окружения).

// Обычная функция
function sum(a, b) {
  return a + b;
}

// Стрелочная функция
const sum = (a, b) => a + b;

// Если один параметр, скобки можно опустить
const double = n => n * 2;

// Без параметров — пустые скобки
const greet = () => console.log('Привет!');

// Если тело состоит из нескольких выражений, нужны фигурные скобки и return
const multiply = (a, b) => {
  const result = a * b;
  return result;
};

Пример с this:

function Timer() {
  this.seconds = 0;
  setInterval(() => {
    this.seconds++; // this — экземпляр Timer, а не window
  }, 1000);
}

3. Шаблонные строки (Template literals)

Обратные кавычки ` позволяют встраивать выражения ${...} и создавать многострочные строки без конкатенации.

const name = 'Анна';
const age = 25;

// Старый способ
const oldGreeting = 'Меня зовут ' + name + ', мне ' + age + ' лет.';

// Новый способ
const greeting = `Меня зовут ${name}, мне ${age} лет.`;

// Многострочность
const multiline = `
  Это первая строка
  А это вторая
`;

4. Деструктуризация (Destructuring)

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

Массивы

const colors = ['red', 'green', 'blue'];
const [first, second] = colors;
console.log(first); // 'red'

// Пропуск элементов
const [, , third] = colors;
console.log(third); // 'blue'

// Значения по умолчанию
const [a, b, c, d = 'yellow'] = colors;

Объекты

const user = {
  id: 1,
  name: 'Иван',
  address: { city: 'Москва' }
};

const { name, id } = user;
console.log(name, id); // 'Иван' 1

// Переименование
const { name: userName } = user;

// Вложенная деструктуризация
const { address: { city } } = user;

5. Spread (…) и Rest (…)

Spread — «разворачивает» элементы массива/объекта.
Rest — собирает оставшиеся аргументы в массив.

Spread для массивов

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1,2,3,4,5,6]

// Копирование массива
const copy = [...arr1];

Spread для объектов (ES2018)

const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, ...obj1 }; // { c:3, a:1, b:2 }

Rest в параметрах функции

function sumAll(...numbers) {
  return numbers.reduce((acc, n) => acc + n, 0);
}
sumAll(1, 2, 3, 4); // 10

6. Параметры по умолчанию

function greet(name = 'Гость', greeting = 'Привет') {
  return `${greeting}, ${name}!`;
}
greet();          // 'Привет, Гость!'
greet('Алексей'); // 'Привет, Алексей!'

7. Классы (Classes)

Синтаксический сахар над прототипным наследованием. Делает ООП в JavaScript более понятным.

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} издаёт звук.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // вызов конструктора родителя
    this.breed = breed;
  }

  speak() {
    console.log(`${this.name} гавкает!`);
  }
}

const dog = new Dog('Рекс', 'овчарка');
dog.speak(); // 'Рекс гавкает!'

8. Модули (Modules)

ES6 вводит родную модульную систему. Код из одного файла можно экспортировать и импортировать в другом.

export.js

export const PI = 3.14;
export function square(x) { return x * x; }
export default class Calculator { ... }

import.js

import Calculator, { PI, square as sq } from './export.js';
console.log(PI);

9. Промисы (Promises) и Async/Await

Промисы — для работы с асинхронными операциями

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true;
      if (success) resolve('Данные получены');
      else reject('Ошибка');
    }, 1000);
  });
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

Async / Await (ES2017) — более удобный синтаксис

async function getData() {
  try {
    const result = await fetchData();
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}

Ключевые методы промисов:

  • Promise.all([p1, p2]) — ждёт все или первый отказ.
  • Promise.race([p1, p2]) — как только один завершится.
  • Promise.allSettled — ждёт все, даже с ошибками (ES2020).

10. Коллекции: Map, Set, WeakMap, WeakSet

Map — словарь с ключами любого типа

const map = new Map();
map.set('name', 'Иван');
map.set(1, 'число');
map.get('name'); // 'Иван'
map.has(1);      // true
map.delete(1);
map.size;        // 1

Set — коллекция уникальных значений

const set = new Set([1, 2, 2, 3]);
console.log(set);        // {1,2,3}
set.add(4);
set.has(2);              // true

WeakMap / WeakSet

Ключи — только объекты, не препятствуют сборке мусора. Итерация недоступна.


11. Новые методы объектов и массивов

Object

  • Object.assign(target, ...sources) — поверхностное копирование свойств.
  • Object.keys(obj), Object.values(obj), Object.entries(obj) — возвращают массивы ключей, значений или пар [key, value].
const user = { id: 1, name: 'Анна' };
Object.entries(user).forEach(([key, value]) => {
  console.log(`${key}: ${value}`);
});

Array

  • Array.from(iterable) — создаёт массив из псевдомассива или итератора.
  • Array.of(1,2,3) — альтернатива конструктору Array().
  • find(callback) / findIndex(callback) — поиск элемента.
  • includes(value) — проверяет наличие (ES2016).
  • flat(depth) и flatMap(callback) — для работы с вложенными массивами (ES2019).
const arr = [1, [2, [3, 4]]];
arr.flat(2);          // [1,2,3,4]

const phrases = ['hello world', 'good morning'];
phrases.flatMap(s => s.split(' ')); // ['hello','world','good','morning']

12. Итераторы и генераторы

Итератор — объект с методом next(), возвращающим { value, done }

const iterable = [1, 2, 3];
const iterator = iterable[Symbol.iterator]();
iterator.next(); // { value:1, done:false }

Генератор — функция, которая может приостанавливать выполнение (yield)

function* idGenerator() {
  let id = 1;
  while (true) {
    yield id++;
  }
}
const gen = idGenerator();
gen.next().value; // 1
gen.next().value; // 2

Итераторы и генераторы лежат в основе for...of, спред-оператора и работы с коллекциями.


13. Дополнительные возможности ES6+

Optional chaining ?. (ES2020)

Безопасный доступ к вложенным свойствам без проверок на null/undefined.

const user = { profile: { name: 'Олег' } };
console.log(user.profile?.name);   // 'Олег'
console.log(user.address?.city);   // undefined (без ошибки)

Nullish coalescing ?? (ES2020)

Возвращает правый операнд, если левый — null или undefined.

const value = null ?? 'default'; // 'default'
const zero = 0 ?? 100;           // 0 (0 не null/undefined)

BigInt (ES2020) — для целых чисел произвольной точности

const bigNumber = 9007199254740991n + 2n;

String.prototype.replaceAll (ES2021)

'hello hello'.replaceAll('hello', 'hi'); // 'hi hi'

14. Краткий справочник по версиям (после ES6)

Версия Ключевые дополнения
ES2016 Array.prototype.includes, оператор ** (возведение в степень)
ES2017 async/await, Object.values(), Object.entries(), String.padStart/padEnd
ES2018 Rest/Spread для объектов, асинхронные итераторы
ES2019 Array.flat(), flatMap(), Object.fromEntries()
ES2020 Optional chaining (?.), Nullish coalescing (??), BigInt, Promise.allSettled
ES2021 String.replaceAll, Promise.any, логические операторы присваивания (`
ES2022 await верхнего уровня, методы .at() для массивов/строк, приватные поля классов #

Практические задания для самопроверки

  1. Перепишите следующий код, используя let, const и стрелочные функции:

    var arr = [1, 2, 3];
    var double = function(arr) { return arr.map(function(x) { return x * 2; }); };
    
  2. Создайте класс Rectangle с полями width, height и методом getArea(). Отнаследуйте класс Square.

  3. Напишите функцию, которая принимает любое количество чисел, суммирует их и возвращает результат (используйте rest-параметр).

  4. Используя деструктуризацию, получите из объекта { title: "JS", author: { name: "John", year: 2020 } } переменные bookTitle и authorName.

  5. Напишите асинхронную функцию, которая загружает данные с фиктивного API (используйте setTimeout с промисом) и выводит результат.

Примерные решения (можно подсмотреть, но лучше попробовать самим).


Заключение

ES6+ кардинально изменил JavaScript, сделав его современным, мощным и удобным языком. Изученные возможности — это фундамент, на котором строится код в React, Angular, Node.js и любых современных проектах. Практикуйтесь, пишите примеры и постепенно внедряйте новые конструкции в свои проекты.

“JavaScript — это не только язык браузера. С ES6 он стал полноценным инструментом для серьёзной разработки.”

Успехов в изучении!