Урок 22

День 22 | Современный JavaScript ES6+

60 мин

Современный JavaScript ES6+

В предыдущем уроке мы изучили основы JavaScript. Теперь давайте изучим современные возможности, которые появились в ES6 (2015) и более новых версиях. Эти фичи делают код более читаемым, коротким и выразительным.

Что такое ES6+? ES6 (ECMAScript 2015) — это версия стандарта JavaScript, которая добавила множество новых возможностей. ES6+ означает ES6 и все последующие версии (ES7, ES8, ES9, ES10, ES11, ES12 и т.д.).

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

Деструктуризация — это способ извлечения значений из массивов и объектов в отдельные переменные. Это очень удобно!

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

// Обычный способ
const colors = ["red", "green", "blue"];
const first = colors[0];
const second = colors[1];
const third = colors[2];

// Деструктуризация
const [first, second, third] = colors;
// first = "red", second = "green", third = "blue"

// Пропуск элементов
const [first, , third] = colors; // Пропускаем второй элемент

// Значения по умолчанию
const [first, second, third = "yellow"] = ["red", "green"];
// third будет "yellow", если элемента нет

Деструктуризация объектов

// Обычный способ
const user = { name: "Иван", age: 25, city: "Москва" };
const name = user.name;
const age = user.age;

// Деструктуризация
const { name, age } = user;
// name = "Иван", age = 25

// Переименование
const { name: userName, age: userAge } = user;
// userName = "Иван", userAge = 25

// Значения по умолчанию
const { name, age, email = "нет" } = user;
// email будет "нет", если свойства нет

// Вложенная деструктуризация
const user = {
  name: "Иван",
  address: {
    city: "Москва",
    street: "Ленина"
  }
};
const { address: { city } } = user;
// city = "Москва"

Практическое применение

// Обмен значений переменных
let a = 1;
let b = 2;
[a, b] = [b, a]; // a = 2, b = 1

// Извлечение из функции
function getUser() {
  return { name: "Иван", age: 25, email: "ivan@example.com" };
}

const { name, email } = getUser();
// name = "Иван", email = "ivan@example.com"

// Параметры функции
function greet({ name, age }) {
  console.log(`Привет, ${name}! Тебе ${age} лет.`);
}

greet({ name: "Иван", age: 25 }); // Привет, Иван! Тебе 25 лет.

Spread оператор (...)

Spread оператор (...) позволяет "разворачивать" массивы и объекты.

Spread с массивами

// Копирование массива
const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // [1, 2, 3] (новая копия)

// Объединение массивов
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// Добавление элементов
const arr = [1, 2, 3];
const newArr = [0, ...arr, 4]; // [0, 1, 2, 3, 4]

// Передача аргументов в функцию
function sum(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];
sum(...numbers); // 6 (эквивалентно sum(1, 2, 3))

Spread с объектами

// Копирование объекта
const user = { name: "Иван", age: 25 };
const userCopy = { ...user }; // { name: "Иван", age: 25 }

// Объединение объектов
const user = { name: "Иван", age: 25 };
const address = { city: "Москва", street: "Ленина" };
const fullUser = { ...user, ...address };
// { name: "Иван", age: 25, city: "Москва", street: "Ленина" }

// Переопределение свойств
const user = { name: "Иван", age: 25 };
const updated = { ...user, age: 26 }; // { name: "Иван", age: 26 }

Rest оператор (...)

Rest оператор (тоже ..., но в другом контексте) позволяет собирать оставшиеся элементы в массив или объект.

Rest в функциях

// Сбор оставшихся аргументов
function sum(first, ...rest) {
  return first + rest.reduce((a, b) => a + b, 0);
}

sum(1, 2, 3, 4); // 10
// first = 1, rest = [2, 3, 4]

// В деструктуризации
const [first, second, ...others] = [1, 2, 3, 4, 5];
// first = 1, second = 2, others = [3, 4, 5]

const { name, ...rest } = { name: "Иван", age: 25, city: "Москва" };
// name = "Иван", rest = { age: 25, city: "Москва" }

Template Literals (шаблонные строки)

Шаблонные строки позволяют вставлять переменные и выражения в строки. Мы уже использовали их, но давайте разберём подробнее.

// Обычная строка (конкатенация)
const name = "Иван";
const greeting = "Привет, " + name + "!";

// Шаблонная строка
const greeting = `Привет, ${name}!`;

// Многострочные строки
const text = `Это
многострочная
строка`;

// Выражения внутри
const a = 5;
const b = 3;
const result = `Сумма ${a} и ${b} равна ${a + b}`;
// "Сумма 5 и 3 равна 8"

Методы массивов ES6+

Array.map()

Создаёт новый массив, преобразуя каждый элемент:

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8]

const users = [
  { name: "Иван", age: 25 },
  { name: "Мария", age: 30 }
];
const names = users.map(user => user.name);
// ["Иван", "Мария"]

Array.filter()

Создаёт новый массив с элементами, прошедшими проверку:

const numbers = [1, 2, 3, 4, 5, 6];
const even = numbers.filter(n => n % 2 === 0);
// [2, 4, 6]

const users = [
  { name: "Иван", age: 25 },
  { name: "Мария", age: 17 },
  { name: "Петр", age: 30 }
];
const adults = users.filter(user => user.age >= 18);
// [{ name: "Иван", age: 25 }, { name: "Петр", age: 30 }]

Array.find() и Array.findIndex()

const users = [
  { id: 1, name: "Иван" },
  { id: 2, name: "Мария" },
  { id: 3, name: "Петр" }
];

const user = users.find(u => u.id === 2);
// { id: 2, name: "Мария" }

const index = users.findIndex(u => u.name === "Мария");
// 1

Array.reduce()

Преобразует массив в одно значение:

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 10

// acc (accumulator) — накопитель
// n — текущий элемент
// 0 — начальное значение

Async/Await

Async/await — это современный способ работы с асинхронным кодом. Он делает код более читаемым, чем промисы.

Промисы (напоминание)

// Создание промиса
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { id: 1, name: "Данные" };
      resolve(data);
    }, 1000);
  });
};

// Использование с then
fetchData()
  .then(data => {
    console.log(data);
    return processData(data);
  })
  .then(result => {
    console.log(result);
  })
  .catch(error => {
    console.error(error);
  });

Async/Await (современный способ)

// Async функция
async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
    const result = await processData(data);
    console.log(result);
    return result;
  } catch (error) {
    console.error("Ошибка:", error);
    throw error;
  }
}

// Использование
getData();

Разберём:

  • async — ключевое слово перед функцией. Делает функцию асинхронной (возвращает промис).
  • await — ключевое слово перед промисом. Ждёт выполнения промиса и возвращает результат.
  • try/catch — обработка ошибок (аналог .catch() для промисов).

Пример с fetch (загрузка данных)

async function loadUsers() {
  try {
    const response = await fetch("/api/users");
    const users = await response.json();
    return users;
  } catch (error) {
    console.error("Ошибка загрузки:", error);
    return [];
  }
}

// Использование
const users = await loadUsers();
console.log(users);

ES Modules (модули)

ES Modules позволяют разбивать код на отдельные файлы и импортировать их. Это стандарт современной разработки!

Экспорт (export)

// math.js
export const PI = 3.14159;

export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}

// Или экспорт по умолчанию
export default function subtract(a, b) {
  return a - b;
}

Импорт (import)

// main.js
// Именованный импорт
import { PI, add, multiply } from "./math.js";

// Импорт по умолчанию
import subtract from "./math.js";

// Импорт всего
import * as math from "./math.js";
// math.PI, math.add(), math.multiply()

// Использование
console.log(PI); // 3.14159
console.log(add(5, 3)); // 8
console.log(subtract(5, 3)); // 2

Важно: В Vite ES Modules работают из коробки! Просто используйте import и export.

Optional Chaining (?.)

Optional chaining позволяет безопасно обращаться к свойствам объектов, которые могут быть null или undefined.

// Обычный способ (может вызвать ошибку)
const user = { name: "Иван", address: { city: "Москва" } };
const city = user.address.city; // "Москва"

// Если address = null, будет ошибка!
const user2 = { name: "Иван", address: null };
const city2 = user2.address.city; // Ошибка!

// Optional chaining
const city3 = user2.address?.city; // undefined (без ошибки)

// С методами
const result = user.someMethod?.(); // Вызов только если метод существует

// С массивами
const first = arr?.[0]; // Первый элемент, если массив существует

Nullish Coalescing (??)

Оператор ?? возвращает правую часть, если левая часть null или undefined.

// Обычный способ
const name = user.name || "Гость";
// Проблема: если name = "", то будет "Гость"

// Nullish coalescing
const name = user.name ?? "Гость";
// Вернёт "Гость" только если name = null или undefined
// Если name = "", вернёт ""

// Пример
const count = 0;
const display = count ?? "нет"; // 0 (не "нет"!)

const count2 = null;
const display2 = count2 ?? "нет"; // "нет"

Практическое задание

  1. Используйте деструктуризацию для извлечения значений из массива и объекта
  2. Примените spread оператор для объединения массивов и объектов
  3. Используйте методы массивов (map, filter, reduce) для обработки данных
  4. Создайте async функцию для загрузки данных (можно использовать setTimeout для имитации)
  5. Разбейте код на модули (создайте отдельный файл и импортируйте его)
  6. Используйте optional chaining для безопасного доступа к свойствам
  7. Примените nullish coalescing для значений по умолчанию

Что дальше?

Отлично! Теперь вы знаете современный JavaScript. В следующем уроке мы изучим HTML формы, а затем создадим форму с валидацией, используя все изученные возможности JavaScript.

Мы используем файлы cookie для улучшения работы сайта и персонализации контента. Продолжая использовать сайт, вы соглашаетесь с использованием cookies в соответствии с нашей Политикой конфиденциальности.