JavaScript — синтаксис, типы
JavaScript (JS) — язык программирования для логики, вычислений и интерактивности в браузере, на сервере и в других средах.
const message = "Привет, JavaScript!";
console.log(message);Комментарии:
// Однострочный комментарий
/* Многострочный комментарий */JavaScript чувствителен к регистру: userName и username — разные имена.
Переменные и области видимости
В современном коде используют const и let. var встречается преимущественно в старом коде.
const appName = "Catalog"; // нельзя присвоить новое значение
let page = 1;
page += 1; // можно изменить
var legacyValue = 10;| Объявление | Повторное объявление | Новое присваивание | Область видимости |
|---|---|---|---|
var |
Да | Да | Функция или глобальная |
let |
Нет | Да | Блок { ... } |
const |
Нет | Нет | Блок { ... } |
const запрещает заменить значение переменной, но не делает объект неизменяемым:
const user = { name: "Анна" };
user.name = "Ирина"; // разрешено
// user = {}; // ошибкаБлочная область видимости
if (true) {
const message = "Внутри блока";
let count = 1;
var oldValue = 2;
}
// console.log(message); // ReferenceError
// console.log(count); // ReferenceError
console.log(oldValue); // 2Переменные функции доступны только внутри неё:
function calculate() {
const result = 2 + 2;
return result;
}Поднятие объявлений
var поднимается и до присваивания содержит undefined:
console.log(value); // undefined
var value = 10;let и const нельзя использовать до объявления. Этот участок называется temporal dead zone:
// console.log(total); // ReferenceError
const total = 10;Практическое правило: используйте const по умолчанию, let — если значение меняется, избегайте var в новом коде.
Типы данных
Примитивные типы
JavaScript имеет семь примитивных типов:
| Тип | Назначение | Пример |
|---|---|---|
string |
Строка | "Привет" |
number |
Целое или дробное число | 42, 3.14 |
bigint |
Большое целое число | 9007199254740993n |
boolean |
Логическое значение | true, false |
undefined |
Значение не задано | undefined |
null |
Намеренно пустое значение | null |
symbol |
Уникальный идентификатор | Symbol("id") |
Примитивы неизменяемы. Объекты, массивы, функции и даты относятся к объектным значениям.
const user = { name: "Анна" };
const colors = ["red", "green"];
const now = new Date();Проверка типа
typeof "text"; // "string"
typeof 42; // "number"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof 10n; // "bigint"
typeof Symbol("id"); // "symbol"
typeof {}; // "object"
typeof function () {}; // "function"Историческая особенность:
typeof null; // "object"Для массива используйте Array.isArray:
Array.isArray([]); // true
Array.isArray({}); // falseКопирование значений
Примитив копируется по значению:
let first = 10;
let second = first;
second = 20;
console.log(first); // 10Объектная переменная хранит ссылку:
const firstUser = { name: "Анна" };
const secondUser = firstUser;
secondUser.name = "Ирина";
console.log(firstUser.name); // ИринаПриведение типов (coercion)
Приведение бывает явным и неявным.
Явное преобразование
String(42); // "42"
String(null); // "null"
Number("42"); // 42
Number(""); // 0
Number(true); // 1
Number(null); // 0
Number(undefined); // NaN
parseInt("42px", 10); // 42
parseFloat("3.14rem"); // 3.14
Boolean(1); // true
Boolean(0); // false
Boolean("text"); // true
Boolean(""); // falseFalsy-значения: false, 0, -0, 0n, NaN, "", null, undefined. Остальные значения truthy, включая [] и {}.
Неявное преобразование
"2" + 3; // "23": число стало строкой
"6" - 2; // 4: строка стала числом
"6" * 2; // 12Данные из форм приходят строками, поэтому их лучше преобразовывать явно:
const price = "100";
const count = 2;
price + count; // "1002"
Number(price) + count; // 102Строгое и нестрогое равенство
"5" == 5; // true: выполнено приведение
"5" === 5; // false: отличаются типы
5 !== 4; // trueОбычно используйте === и !==.
NaN не равен самому себе, поэтому проверяется специальным методом:
const result = Number("abc");
result === NaN; // false
Number.isNaN(result); // trueОператоры
Арифметические и операторы присваивания
| Оператор | Назначение | Пример |
|---|---|---|
+ |
Сложение или конкатенация | 2 + 3, "a" + "b" |
- |
Вычитание | 5 - 2 |
* |
Умножение | 3 * 4 |
/ |
Деление | 10 / 2 |
% |
Остаток | 7 % 3 |
** |
Степень | 2 ** 3 |
++, -- |
Изменение на единицу | count++ |
let total = 10;
total += 5;
total -= 2;
total *= 3;
total /= 2;Сравнение и логика
5 === 5; // равно
5 !== 4; // не равно
5 > 3;
5 >= 5;
2 < 4;
2 <= 2;
isAdult && hasTicket; // И
isAdmin || isEditor; // ИЛИ
!isOpen; // НЕ&& и || возвращают операнды, а не обязательно boolean:
const name = inputName || "Гость"; // первое truthy
const title = data && data.title; // первое falsy или последнееНулевое слияние и optional chaining
?? использует запасное значение только для null и undefined:
const count = 0;
count || 10; // 10
count ?? 10; // 0?. безопасно обращается к вложенному свойству или методу:
const city = user?.address?.city;
callback?.();Другие операторы
"name" in user; // свойство есть в объекте или прототипе
Object.hasOwn(user, "name"); // собственное свойство
typeof value;
delete user.temporary;Скобки явно задают порядок вычислений:
const result = (2 + 3) * 4; // 20Условные конструкции
if/else
const temperature = 22;
if (temperature > 25) {
console.log("Жарко");
} else if (temperature < 10) {
console.log("Холодно");
} else {
console.log("Комфортно");
}Условие приводится к boolean:
if (items.length > 0) {
console.log("Список не пуст");
}switch
switch сопоставляет значения через строгое сравнение:
switch (status) {
case "loading":
console.log("Загрузка...");
break;
case "success":
console.log("Готово");
break;
case "error":
console.log("Ошибка");
break;
default:
console.log("Неизвестный статус");
}Без break выполнение перейдёт к следующей ветви. Несколько вариантов можно объединить:
switch (role) {
case "admin":
case "editor":
console.log("Можно редактировать");
break;
default:
console.log("Только просмотр");
}Тернарный оператор
const access = age >= 18 ? "Разрешён" : "Запрещён";Тернарный оператор удобен для короткого выбора значения. Для сложной логики предпочтительнее if/else.
Циклы
for
for (let index = 0; index < 3; index += 1) {
console.log(index); // 0, 1, 2
}Обход массива по индексам:
const numbers = [10, 20, 30];
for (let index = 0; index < numbers.length; index += 1) {
console.log(numbers[index]);
}while и do...while
let attempts = 0;
while (attempts < 3) {
console.log(attempts);
attempts += 1;
}do...while выполняет тело хотя бы один раз:
let value = 0;
do {
console.log(value);
value += 1;
} while (value < 3);for...of
Перебирает значения массива, строки, Set, Map и других итерируемых объектов:
const colors = ["red", "green", "blue"];
for (const color of colors) {
console.log(color);
}for...in
Перебирает имена перечисляемых свойств объекта:
const user = { name: "Анна", age: 30 };
for (const key in user) {
console.log(key, user[key]);
}Для массивов обычно используйте for...of, а не for...in: последний возвращает индексы как строки и может учитывать дополнительные свойства.
break и continue
for (let number = 1; number <= 10; number += 1) {
if (number === 4) break; // завершить цикл
if (number % 2 === 0) continue; // пропустить итерацию
console.log(number);
}Функции
Функция принимает параметры, выполняет код и может вернуть значение через return.
Объявление функции
function add(a, b) {
return a + b;
}
add(2, 3); // 5Объявление функции можно вызвать до его строки благодаря поднятию.
Функциональное выражение
const multiply = function (a, b) {
return a * b;
};Выражение доступно только после присваивания переменной.
Стрелочная функция
const subtract = (a, b) => {
return a - b;
};
const square = number => number ** 2;
const sum = (a, b) => a + b;Возврат объекта:
const createUser = name => ({ name, active: true });У стрелочной функции нет собственного this и arguments: она берёт this из внешнего контекста.
Параметры по умолчанию
function greet(name = "Гость") {
return `Привет, ${name}!`;
}
greet(); // Привет, Гость!
greet("Ирина"); // Привет, Ирина!Значение по умолчанию применяется при undefined, но не при null.
Rest-параметры и деструктуризация
function sum(...numbers) {
return numbers.reduce((total, number) => total + number, 0);
}
function printUser({ name, age }) {
console.log(`${name}: ${age}`);
}
function createSettings({ theme = "light" } = {}) {
return { theme };
}Замыкание
Внутренняя функция сохраняет доступ к внешним переменным:
function createCounter() {
let count = 0;
return () => {
count += 1;
return count;
};
}
const counter = createCounter();
counter(); // 1
counter(); // 2Функцию, переданную другой функции, называют колбэком:
const doubled = [1, 2, 3].map(number => number * 2);Строки
Строки неизменяемы: методы возвращают новую строку.
const original = "hello";
const upper = original.toUpperCase();Основные свойства и методы
const text = " JavaScript — это язык ";
text.length;
text[2];
text.at(-1); // последний символ
text.trim();
text.toUpperCase();
text.toLowerCase();
text.includes("язык");
text.startsWith(" Java");
text.endsWith("язык ");
text.indexOf("Script");
text.slice(2, 12);
text.replace("язык", "language");
text.replaceAll(" ", "-");Разделение и объединение:
const colors = "red,green,blue".split(",");
const result = colors.join(" | ");Нормализация ввода:
const normalized = " YES ".trim().toLowerCase();
normalized === "yes"; // trueШаблонные литералы
Записываются в обратных кавычках, поддерживают ${...} и многострочный текст:
const name = "Анна";
const age = 25;
const message = `Пользователь: ${name}, возраст: ${age}`;
const html = `
<article class="card">
<h2>${name}</h2>
</article>
`;Числа и Math
Числа
const integer = 100;
const decimal = 12.5;
const million = 1_000_000;
const binary = 0b1010; // 10
const hexadecimal = 0xA; // 10Проверки:
Number.isNaN(NaN); // true
Number.isFinite(10); // true
Number.isInteger(10); // true
Number.isSafeInteger(42); // trueМетоды Math
Math.round(4.5); // 5
Math.floor(4.9); // 4
Math.ceil(4.1); // 5
Math.trunc(4.9); // 4
Math.abs(-10); // 10
Math.sqrt(81); // 9
Math.min(4, 1, 8); // 1
Math.max(4, 1, 8); // 8
2 ** 3; // 8Случайное целое от min до max включительно:
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}Math.random() не подходит для паролей и токенов.
Форматирование и точность
const value = 12.3456;
value.toFixed(2); // "12.35" — строка
new Intl.NumberFormat("ru-RU", {
maximumFractionDigits: 2,
}).format(1234567.89);Дроби представлены в двоичном формате:
0.1 + 0.2; // 0.30000000000000004
const isEqual = Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON;Работа с датами (Date)
Date хранит момент времени как число миллисекунд с 1 января 1970 года, 00:00:00 UTC.
Создание
const now = new Date();
const timestamp = Date.now();
const fromISO = new Date("2026-05-20T12:30:00Z");
const fromParts = new Date(2026, 4, 20, 12, 30);В числовом конструкторе месяцы начинаются с нуля: 0 — январь, 4 — май. Для строк используйте ISO 8601. Суффикс Z означает UTC.
Получение и изменение компонентов
const date = new Date();
date.getFullYear();
date.getMonth(); // 0–11
date.getDate(); // день месяца
date.getDay(); // день недели, воскресенье — 0
date.getHours();
date.getMinutes();
date.setFullYear(2030);
date.setMonth(0);
date.setDate(15);Методы set... изменяют объект. Копия даты:
const copy = new Date(date);
copy.setDate(copy.getDate() + 7);Для UTC применяются методы getUTC... и setUTC....
Форматирование
const date = new Date("2026-05-20T12:30:00Z");
date.toISOString();
date.toUTCString();
date.toLocaleDateString("ru-RU");
date.toLocaleString("ru-RU");
const formatter = new Intl.DateTimeFormat("ru-RU", {
dateStyle: "long",
timeStyle: "short",
});
formatter.format(date);Сравнение и проверка
const first = new Date("2026-01-01");
const second = new Date("2026-02-01");
first < second; // true
const invalid = new Date("not-a-date");
Number.isNaN(invalid.getTime()); // trueПри работе с датами учитывайте локальный часовой пояс, UTC и переходы на летнее время.
Обработка ошибок
Для создания ошибки используют throw:
function divide(a, b) {
if (b === 0) {
throw new Error("Деление на ноль невозможно");
}
return a / b;
}try/catch/finally
try {
const data = JSON.parse('{"name":"Анна"}');
console.log(data.name);
} catch (error) {
console.error(error.name);
console.error(error.message);
console.error(error.stack);
} finally {
console.log("Операция завершена");
}finally выполняется независимо от результата и подходит для очистки состояния.
Встроенные типы ошибок:
new Error("Общая ошибка");
new TypeError("Неверный тип");
new RangeError("Вне диапазона");
new SyntaxError("Ошибка синтаксиса");Если ошибка не может быть обработана на текущем уровне, её пробрасывают выше:
try {
JSON.parse("invalid");
} catch (error) {
if (error instanceof SyntaxError) {
console.error("Некорректный JSON");
} else {
throw error;
}
}Для асинхронной операции try/catch используется вместе с await:
async function loadData() {
try {
const response = await fetch("/api/data");
return await response.json();
} catch (error) {
console.error("Ошибка загрузки", error);
return null;
}
}Не оставляйте пустой catch: он скрывает причину сбоя.
Отладка через console
Основные методы
console.log("Обычное сообщение");
console.warn("Предупреждение");
console.error("Ошибка");Можно выводить несколько значений или объект с именем переменной:
const user = { name: "Анна", age: 28 };
console.log("Пользователь:", user);
console.log({ user });Дополнительные методы:
console.table([
{ name: "Анна", age: 28 },
{ name: "Олег", age: 32 },
]);
console.group("Загрузка");
console.log("Шаг 1");
console.log("Шаг 2");
console.groupEnd();
console.time("calculation");
// операции
console.timeEnd("calculation");
console.assert(2 + 2 === 4, "Ошибка проверки");
console.dir(document.querySelector(".card"));Для сложной отладки используйте точки останова во вкладке DevTools Sources. Временные console.log не следует оставлять в рабочем коде без необходимости.
Краткие рекомендации
- Используйте
constпо умолчанию,let— для изменяемого значения. - Избегайте
varв новом коде. - Предпочитайте
===и!==. - Явно преобразуйте внешние данные.
- Используйте
for...ofдля значений массива,for...in— для ключей объекта. - Проверяйте
NaNчерезNumber.isNaN. - Помните, что
toFixed()возвращает строку. - Учитывайте локальное время и UTC при работе с
Date. - Не скрывайте ошибки пустым
catch. - Удаляйте лишние отладочные сообщения перед выпуском.
Общий пример
const tasks = [];
function addTask(taskName = "Без названия") {
const normalizedName = taskName.trim();
if (!normalizedName) {
throw new Error("Название задачи не может быть пустым");
}
tasks.push({
title: normalizedName,
createdAt: new Date(),
});
}
try {
addTask(" Изучить циклы ");
for (const task of tasks) {
const date = task.createdAt.toLocaleDateString("ru-RU");
console.log(`${task.title} — ${date}`);
}
} catch (error) {
console.error("Не удалось добавить задачу", error);
}В примере используются const, массив, функция с параметром по умолчанию, строковый метод trim, if, throw, Date, цикл for...of, шаблонный литерал и try/catch.