О нас Руководства Проекты Контакты
Админка
пожалуйста подождите

JavaScript значительно эволюционировал со времён ES6 (2015), получив функции, которые делают код более читаемым, поддерживаемым и мощным. Понимание современного JavaScript — от destructuring до async/await — необходимо для написания профессионального кода. В этом руководстве рассматриваются ключевые возможности современного JavaScript с точки зрения senior-разработчика.

Почему современный JavaScript важен

Современный JavaScript обеспечивает:

  1. Более чистый код: меньше шаблонного кода, больше выразительности
  2. Меньше ошибок: возможности, предотвращающие распространённые ошибки
  3. Лучшую производительность: оптимизированные возможности языка
  4. Работу с async: элегантное асинхронное программирование
  5. Функциональные паттерны: поддержка функций как объектов первого класса

Объявление переменных

let и const

// const: нельзя переназначать (используйте по умолчанию)
const API_URL = 'https://api.example.com';
const config = { timeout: 5000 };
// Можно изменять свойства const-объектов
config.timeout = 10000; // OK
// config = {}; // Ошибка: нельзя переназначить
// let: можно переназначать (используйте при необходимости)
let count = 0;
count = 1; // OK
// Блочная область видимости
if (true) {
const scoped = 'only here';
let alsoScoped = 'only here too';
}
// scoped и alsoScoped здесь недоступны
// Проблемы hoisting у var (избегайте var)
console.log(x); // undefined (поднято hoisting)
var x = 5;

Destructuring

Destructuring объектов

const user = {
name: 'John',
email: '[email protected]',
address: {
city: 'NYC',
zip: '10001'
}
};
// Базовый destructuring
const { name, email } = user;
console.log(name); // 'John'
// Переименование переменных
const { name: userName, email: userEmail } = user;
console.log(userName); // 'John'
// Значения по умолчанию
const { role = 'user' } = user;
console.log(role); // 'user' (не существует в user)
// Вложенный destructuring
const { address: { city, zip } } = user;
console.log(city); // 'NYC'
// Оператор rest
const { name: n, ...rest } = user;
console.log(rest); // { email: '...', address: {...} }
// Параметры функции
function greet({ name, email }) {
console.log(`Hello ${name} (${email})`);
}
greet(user);
// Со значениями по умолчанию в параметрах
function createUser({ name = 'Anonymous', role = 'user' } = {}) {
return { name, role };
}
createUser(); // { name: 'Anonymous', role: 'user' }

Destructuring массивов

const colors = ['red', 'green', 'blue', 'yellow'];
// Базовый destructuring массива
const [first, second] = colors;
console.log(first); // 'red'
// Пропуск элементов
const [, , third] = colors;
console.log(third); // 'blue'
// Оператор rest
const [primary, ...others] = colors;
console.log(others); // ['green', 'blue', 'yellow']
// Значения по умолчанию
const [a, b, c, d, e = 'purple'] = colors;
console.log(e); // 'purple'
// Обмен значений переменных
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1
// Возврат из функции
function getCoordinates() {
return [40.7128, -74.0060];
}
const [lat, lng] = getCoordinates();

Оператор spread

Массивы

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Объединение массивов
const combined = [...arr1, ...arr2];
// [1, 2, 3, 4, 5, 6]
// Копирование массива (поверхностное)
const copy = [...arr1];
// Добавление элементов
const withExtra = [0, ...arr1, 4];
// [0, 1, 2, 3, 4]
// Преобразование iterable в массив
const chars = [...'hello'];
// ['h', 'e', 'l', 'l', 'o']
// Аргументы функции
function sum(a, b, c) {
return a + b + c;
}
sum(...arr1); // 6

Объекты

const defaults = { theme: 'light', lang: 'en' };
const userPrefs = { theme: 'dark' };
// Слияние объектов (поздние свойства имеют приоритет)
const settings = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'en' }
// Копирование объекта (поверхностное)
const copy = { ...defaults };
// Добавление/переопределение свойств
const extended = { ...defaults, fontSize: 16 };
// Условный spread
const extra = true;
const obj = {
required: 'value',
...(extra && { optional: 'included' })
};

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

const name = 'John';
const age = 30;
// Интерполяция строк
const greeting = `Hello, ${name}! You are ${age} years old.`;
// Выражения в шаблонах
const message = `Next year you'll be ${age + 1}`;
// Многострочные строки
const html = `
<div class="card">
<h2>${name}</h2>
<p>Age: ${age}</p>
</div>
`;
// Тегированные шаблоны
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] ? `<strong>${values[i]}</strong>` : '';
return result + str + value;
}, '');
}
const highlighted = highlight`Hello ${name}, you are ${age}!`;
// 'Hello <strong>John</strong>, you are <strong>30</strong>!'

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

// Базовый синтаксис
const add = (a, b) => a + b;
// Один параметр (скобки не нужны)
const double = x => x * 2;
// Без параметров
const getRandom = () => Math.random();
// Многострочная (нужны фигурные скобки и return)
const calculate = (a, b) => {
const sum = a + b;
const product = a * b;
return { sum, product };
};
// Возврат object literal (оберните в скобки)
const createUser = (name, email) => ({ name, email });
// Методы массивов
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
// Лексический this (нет собственного связывания this)
const obj = {
name: 'Object',
greet() {
// Стрелочная функция наследует this из greet()
setTimeout(() => {
console.log(this.name); // 'Object'
}, 100);
}
};

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

const users = [
{ id: 1, name: 'John', age: 30 },
{ id: 2, name: 'Jane', age: 25 },
{ id: 3, name: 'Bob', age: 35 }
];
// map: преобразовать каждый элемент
const names = users.map(u => u.name);
// ['John', 'Jane', 'Bob']
// filter: оставить подходящие элементы
const adults = users.filter(u => u.age >= 30);
// [{ id: 1, ... }, { id: 3, ... }]
// find: получить первый подходящий элемент
const john = users.find(u => u.name === 'John');
// { id: 1, name: 'John', age: 30 }
// findIndex: получить индекс первого совпадения
const johnIndex = users.findIndex(u => u.name === 'John');
// 0
// some: проверить, есть ли хотя бы одно совпадение
const hasAdult = users.some(u => u.age >= 18);
// true
// every: проверить, все ли совпадают
const allAdults = users.every(u => u.age >= 18);
// true
// reduce: свести к одному значению
const totalAge = users.reduce((sum, u) => sum + u.age, 0);
// 90
// Цепочки вызовов
const result = users
.filter(u => u.age >= 30)
.map(u => u.name)
.sort();
// ['Bob', 'John']
// includes
const hasJohn = names.includes('John'); // true
// flat: «расплющить» вложенные массивы
const nested = [[1, 2], [3, 4], [5]];
const flat = nested.flat(); // [1, 2, 3, 4, 5]
// flatMap: map + flat
const sentences = ['Hello World', 'Goodbye World'];
const words = sentences.flatMap(s => s.split(' '));
// ['Hello', 'World', 'Goodbye', 'World']

Сокращённая запись объектов

const name = 'John';
const age = 30;
// Сокращённая запись свойств
const user = { name, age };
// То же самое, что: { name: name, age: age }
// Сокращённая запись методов
const obj = {
greet() {
return 'Hello';
},
// То же самое, что: greet: function() { return 'Hello'; }
};
// Вычисляемые имена свойств
const key = 'dynamicKey';
const dynamic = {
[key]: 'value',
[`${key}_backup`]: 'backup'
};
// { dynamicKey: 'value', dynamicKey_backup: 'backup' }

Optional chaining и nullish coalescing

const user = {
name: 'John',
address: {
city: 'NYC'
}
};
// Optional chaining (?.)
const zip = user?.address?.zip; // undefined (без ошибки)
const country = user?.address?.country?.code; // undefined
// Без optional chaining (по-старому)
const zipOld = user && user.address && user.address.zip;
// С массивами
const first = users?.[0]?.name;
// С функциями
const result = obj?.method?.();
// Nullish coalescing (??)
// Возвращает правую часть только если левая равна null или undefined
const value = null ?? 'default'; // 'default'
const zero = 0 ?? 'default'; // 0 (0 не является nullish)
const empty = '' ?? 'default'; // '' (пустая строка не является nullish)
// Сравнение с || (проверка на falsy)
const valueOr = null || 'default'; // 'default'
const zeroOr = 0 || 'default'; // 'default' (0 — falsy!)
// Комбинирование
const setting = config?.theme ?? 'light';

Async/Await

// Базовая async-функция
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
}
// Обработка ошибок
async function fetchUserSafe(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Failed to fetch user:', error);
return null;
}
}
// Параллельное выполнение
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
return { users, posts };
}
// Последовательное выполнение
async function fetchSequential() {
const user = await fetchUser(1);
const posts = await fetchPosts(user.id); // Зависит от user
return { user, posts };
}
// Async-стрелочная функция
const getUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
};

Модули (Import/Export)

// Именованные exports (utils.js)
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Calculator { }
// Default export (User.js)
export default class User {
constructor(name) {
this.name = name;
}
}
// Именованные imports
import { PI, add } from './utils.js';
// Переименование imports
import { add as sum } from './utils.js';
// Импортировать всё как namespace
import * as utils from './utils.js';
utils.add(1, 2);
// Default import
import User from './User.js';
// Смешанный
import User, { helper } from './User.js';
// Динамический import
const module = await import('./heavy-module.js');

Ключевые выводы

  1. По умолчанию используйте const: используйте let только когда требуется переназначение
  2. Делайте destructuring заранее: упрощайте параметры функций и присваивания
  3. Spread для иммутабельности: создавайте новые массивы/объекты вместо мутаций
  4. Стрелочные функции для callback: более чистый синтаксис, лексический this
  5. Optional chaining для безопасности: избегайте ошибок вида «cannot read property of undefined»
  6. async/await вместо promises: более читаемый async-код

Современные возможности JavaScript — это не просто синтаксический сахар: они позволяют применять паттерны, делающие код более надёжным и поддерживаемым.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
Зетка Интерактив