🟨 JavaScript
Полный справочник: переменные, типы и приведение, функции, объекты, массивы, async/await, event loop, модули, DOM, ошибки и подводные камни.
Шпаргалки · Программирование · #js #javascript #web #node
Запуск и окружение
| Где | Как |
|---|---|
| Браузер | <script type="module" src="app.js"></script>, консоль DevTools (F12) |
| Node.js | node app.js, node --watch app.js, REPL node |
| Менеджеры пакетов | npm, pnpm, yarn, bun |
| Среды | Node.js, Deno, Bun |
| Редакторы | VS Code, WebStorm |
Стандарт языка называется ECMAScript (ES2015, …, ES2025). Новые возможности работают в современных браузерах и Node 20+.
Переменные и области видимости
const PI = 3.14; // нельзя переприсвоить (но объект внутри можно менять)
let counter = 0; // блочная область, можно менять
var old = 1; // функциональная область, всплытие: избегайте
var |
let |
const |
|
|---|---|---|---|
| Область | функция | блок {} |
блок {} |
| Переприсваивание | да | да | нет |
| Всплытие | значение undefined |
зона «мёртвого времени» (ошибка до объявления) | то же |
| Повторное объявление | можно | нельзя | нельзя |
По умолчанию пишите const, let только если значение меняется.
Типы данных
| Тип | Примеры |
|---|---|
number |
42, 3.14, NaN, Infinity |
bigint |
10n, 2n ** 64n |
string |
'a', "b", `x=${x}` |
boolean |
true, false |
null, undefined |
пусто намеренно / не задано |
symbol |
Symbol('id') |
object |
{}, [], функции, Date, Map |
typeof 5; // 'number'
typeof null; // 'object' (историческая ошибка)
Array.isArray([]); // true
Number.isInteger(5); Number.isNaN(NaN); Number.isFinite(1);
Ложные значения (falsy)
false, 0, -0, 0n, '', null, undefined, NaN. Всё остальное истинно, включая '0', [], {}.
Приведение типов
Number('42'); // 42 Number('') // 0 Number('abc') // NaN
parseInt('42px', 10); // 42
parseFloat('3.14abc'); // 3.14
String(123); (123).toString(); `${123}`;
Boolean('a'); !!value;
'5' + 1; // '51' (склейка)
'5' - 1; // 4
Сравнивайте === и !==: == приводит типы (0 == '' истинно, null == undefined истинно).
Операторы
| Группа | Операторы |
|---|---|
| Арифметика | + - * / % ** ++ -- |
| Сравнение | === !== < > <= >= |
| Логика | `&& |
| Null-безопасность | ?? (по умолчанию для null/undefined), ?. (безопасный доступ), ?.(), ?.[] |
| Присваивание | = += -= *= /= **= ??= ||= &&= |
| Прочее | ... (spread / rest), typeof, instanceof, in, delete, void, , |
const city = user?.address?.city ?? 'не указан';
config.timeout ??= 3000; // присвоить, если null/undefined
a ||= 'x'; // если a ложно
const [x, y] = [1, 2]; [x, y] = [y, x]; // обмен значениями
Разница ?? и ||: 0 || 5 даёт 5, а 0 ?? 5 даёт 0.
Условия
if (n > 0) {} else if (n === 0) {} else {}
const label = n > 0 ? '+' : '-';
switch (x) { case 1: …; break; case 2: case 3: …; break; default: … }
Циклы
for (let i = 0; i < 3; i++) {}
for (const v of [1, 2, 3]) {} // значения массивов, строк, Map, Set
for (const k in obj) {} // ключи объекта (включая унаследованные)
for (const [k, v] of Object.entries(obj)) {}
while (cond) {} do {} while (cond);
arr.forEach((v, i) => {}); // без break; для await не подходит
break; continue; outer: for (...) { break outer; }
Функции
function add(a, b = 0) { return a + b; } // объявление (всплывает)
const mul = (a, b) => a * b; // стрелочная: нет своих this и arguments
const sum = (...nums) => nums.reduce((s, n) => s + n, 0); // rest
add(...[1, 2]); // spread
const curry = (a) => (b) => a + b; // замыкание
(() => { /* IIFE */ })();
- Замыкание: функция помнит переменные места создания.
this: у обычной функции зависит от вызова (obj.f()→obj), у стрелочной берётся из окружения. Явно:f.call(obj, a),f.apply(obj, [a]),f.bind(obj).- Параметры по значению для примитивов, для объектов копируется ссылка.
Объекты
const user = { name: 'Аня', age: 30, 'full-name': 'x', [key]: 1, greet() { return this.name; } };
user.name; user['full-name']; delete user.age;
const { name, age = 18, ...rest } = user; // деструктуризация
const copy = { ...user, age: 31 }; // поверхностная копия
const deep = structuredClone(user); // глубокая копия
| Метод | Что делает |
|---|---|
Object.keys / values / entries(o) |
ключи / значения / пары |
Object.fromEntries(pairs) |
пары в объект |
Object.assign(a, b) |
слить в a |
Object.freeze(o) |
запретить изменения (поверхностно) |
Object.hasOwn(o, 'k') |
свой ключ |
JSON.stringify(o) / JSON.parse(s) |
сериализация |
Классы
class User {
#password; // приватное поле
static count = 0;
constructor(name, pw) { this.name = name; this.#password = pw; User.count++; }
get label() { return `@${this.name}`; }
check(pw) { return pw === this.#password; }
static create(name) { return new User(name, ''); }
}
class Admin extends User { constructor(n) { super(n, ''); } }
new Admin('root') instanceof User; // true
Массивы
const a = [3, 1, 2];
a.push(4); a.pop(); a.shift(); a.unshift(0); a.splice(1, 1); // изменяют массив
a.at(-1); a.slice(1, 3); a.concat([5]); a.includes(2); a.indexOf(2);
a.map(x => x * 2); a.filter(x => x > 1); a.find(x => x > 1); a.findLast(x => x < 3);
a.some(x => x > 2); a.every(x => x > 0);
a.reduce((s, x) => s + x, 0);
a.flat(2); a.flatMap(x => [x, x]);
a.join(', '); Array.from({ length: 3 }, (_, i) => i); Array.of(1, 2);
Сортировка: [...a].sort((x, y) => x - y) (без аргумента сортирует как строки!). Иммутабельные версии (ES2023): toSorted(), toReversed(), toSpliced(), with(i, v). Группировка: Object.groupBy(arr, fn) (современные среды).
Map, Set, WeakMap
const m = new Map([['a', 1]]); m.set('b', 2); m.get('a'); m.has('a'); m.delete('a'); m.size;
for (const [k, v] of m) {}
const s = new Set([1, 1, 2]); s.add(3); s.has(2); [...s];
const unique = [...new Set(arr)];
Map лучше обычного объекта для словарей с произвольными ключами. WeakMap / WeakSet не мешают сборке мусора.
Строки (кратко)
includes, startsWith, endsWith, indexOf, slice, split, trim, padStart, replaceAll, at, repeat, toUpperCase, localeCompare, normalize, matchAll. Подробности в шпаргалке «JS: методы строк».
Числа, даты, Intl
Math.max(...a); Math.min(); Math.round(); Math.floor(); Math.ceil(); Math.trunc(); Math.random(); Math.abs(); Math.pow(2, 3);
(0.1 + 0.2).toFixed(2); // '0.30' (строка); 0.1 + 0.2 !== 0.3
new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB' }).format(1234.5);
new Date().toISOString(); new Date('2026-01-31T10:00:00Z'); Date.now();
new Intl.DateTimeFormat('ru-RU', { dateStyle: 'long' }).format(new Date());
Деньги храните целыми числами в копейках или используйте BigInt / библиотеки.
Итераторы и генераторы
function* ids() { let i = 0; while (true) yield i++; }
const it = ids(); it.next().value;
for await (const chunk of asyncIterable) {}
Асинхронность
JavaScript однопоточный. Event loop: синхронный код → микрозадачи (Promise.then, queueMicrotask) → макрозадачи (setTimeout, события, I/O).
console.log(1); setTimeout(() => console.log(2)); Promise.resolve().then(() => console.log(3)); console.log(4);
// 1 4 3 2
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function load(id, signal) {
const res = await fetch(`/api/items/${id}`, { signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 5000); // отмена по таймауту
try { const data = await load(1, ctrl.signal); } catch (e) { console.error(e); }
| Комбинатор | Поведение |
|---|---|
Promise.all([...]) |
все, падает при первой ошибке |
Promise.allSettled([...]) |
результаты всех, без падения |
Promise.race([...]) |
первый завершившийся |
Promise.any([...]) |
первый успешный |
Параллельно: await Promise.all(ids.map(load)). Последовательно: цикл for ... of с await внутри. Не используйте await в forEach.
Ошибки
try { JSON.parse(text); } catch (e) { if (e instanceof SyntaxError) {} else throw e; } finally { cleanup(); }
class HttpError extends Error { constructor(status, msg) { super(msg); this.name = 'HttpError'; this.status = status; } }
throw new Error('что-то пошло не так', { cause: err });
Необработанные отклонения: process.on('unhandledRejection', …) (Node), window.addEventListener('unhandledrejection', …).
Модули
// ESM
export const a = 1; export default function f() {}
import f, { a } from './mod.js'; const lazy = await import('./heavy.js');
// CommonJS (Node, старый)
const fs = require('fs'); module.exports = { f };
В Node для ESM: "type": "module" в package.json или расширение .mjs.
Регулярные выражения
/(\d{4})-(\d{2})/.exec('2026-05'); // группы
'a1b2'.replace(/\d/g, '#'); // 'a#b#'
const { groups } = /(?<y>\d{4})-(?<m>\d{2})/.exec('2026-05');
Флаги: g все, i без регистра, m строки, s точка и перенос, u Unicode, y липкий.
DOM (браузер)
const el = document.querySelector('.card'); document.querySelectorAll('li');
el.textContent = 'текст'; el.innerHTML = '…'; // innerHTML опасен для чужих данных (XSS)
el.classList.add('on'); el.classList.toggle('on'); el.setAttribute('id', 'x'); el.dataset.id;
document.createElement('div'); parent.append(el); el.remove();
el.addEventListener('click', (e) => { e.preventDefault(); }, { once: true });
parent.addEventListener('click', (e) => e.target.closest('button')); // делегирование
localStorage.setItem('k', JSON.stringify(v)); sessionStorage; new URL(location.href).searchParams.get('q');
Подводные камни
0.1 + 0.2 !== 0.3: сравнивайте с допуском.typeof null === 'object',NaN !== NaN(Number.isNaN).sort()по умолчанию лексикографический.parseInt('08')без основания: всегда указывайте10.- Мутация общих объектов при поверхностной копии.
thisтеряется при передаче метода как колбэка: используйте стрелку илиbind.- Утечки: неснятые слушатели и таймеры.
Библиотеки и инструменты по задачам
| Задача | Что взять |
|---|---|
| Сервер | Express, Fastify, Hono, NestJS |
| UI | React, Vue, Svelte, Angular, Solid |
| Сборка | Vite, esbuild, Rollup, webpack |
| HTTP | fetch, axios, ky |
| Даты | date-fns, Day.js, Temporal (новый стандарт) |
| Валидация | zod, valibot, Yup |
| Состояние | Redux Toolkit, Zustand, Pinia, TanStack Query |
| Утилиты | lodash-es |
| Тесты | Vitest, Jest, Playwright, Testing Library |
| Качество кода | ESLint, Prettier, TypeScript |