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("");        // false

Falsy-значения: 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 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.