JS · Урок 7

Введение в JavaScript

JavaScript оживляет страницы. Начинаем с переменных, типов данных и первой программы.

Зачем нужен JavaScript

HTML — скелет, CSS — внешность, JavaScript — мозг. На JS писались и простейшие счётчики кликов, и сложные веб-приложения вроде Google Maps. Он выполняется прямо в браузере пользователя.

Как подключить

Файл подключается в конце <body>, чтобы страница успела отрисоваться до выполнения скрипта:

<script src="js/main.js"></script>

Переменные

Переменная — именованное хранилище данных. Три способа объявления:

const siteName = "WebDev";      // не изменится
let count = 0;                 // будет меняться
var oldStyle = 1;              // устаревший способ

count = count + 1;                 // меняем значение
⚠️
Современный стандарт: const по умолчанию, let — когда значение действительно будет меняться. var лучше не использовать.

Типы данных

ТипПример
Число42, 3.14
Строка"Привет", 'мир', `` `шаблон ${x}` ``
Логическоеtrue / false
nullnull — намеренно пусто
undefinedзначения нет вовсе
Массив[1, 2, 3]
Объект{ name: "Аня", age: 25 }
const student = {
  name: "Аня",
  age: 25,
  tech: ["HTML", "CSS", "JS"]
};

console.log(student.name);      // "Аня"
console.log(student.tech[0]); // "HTML"

Операции с числами и строками

let a = 10;
let b = 3;
console.log(a + b);   // 13
console.log(a - b);   // 7
console.log(a * b);   // 30
console.log(a / b);   // 3.333...
console.log(a % b);   // 1 (остаток)
console.log(a ** 2); // 100 (степень)

const name = "Мир";
console.log("Привет, " + name);  // склейка
console.log(`Привет, ${name}!`); // интерполяция
💡
Оператор % (остаток от деления) очень полезен: проверка чётности x % 2 === 0 или «секундомер каждые 2 сек».

Работа с числами: живой пример

Посчитаем: сколько будет 345 × 678?

Нажмите кнопку...

Преобразование типов

JS автоматически превращает типы, но в самый нужный момент лучше управлять этим руками:

const str = "42";
const num = Number(str);        // число 42
const back = String(num);       // строка "42"
const ok = Boolean(1);        // true
const rounded = Math.round("3.7"); // 4

console.log("5" + 3);   // "53" — конкатенация! Не 8
console.log("5" - 3);   // 2 — вычитание работает с числами
⚠️
Значения из форм всегда приходят строками. Не забудьте обернуть их в Number(...) — иначе 1 + 1 даст «11» (!). Классика багов новичков.

Методы строк

У строк куча готовых методов, меняющих регистр, отрезающих и подменяющих части:

const name = "Анна";

name.length;               // 4
name.toUpperCase();        // "АННА"
name.toLowerCase();        // "анна"
name.trim();               // убрать пробелы по краям
name.includes("нн");     // true
name.startsWith("А");    // true
name.slice(0, 2);       // "Ан"
name.replace("Анна", "Иванова"); // "Иванова"
💡
Строки неизменяемы: методы не меняют исходную, а возвращают новую. Поэтому всегда записывайте результат в переменную.

Методы массивов на практике

Массивы сопровождают каждую задачу: список задач, товары корзины, комментарии:

const cart = ["хлеб", "молоко"];
cart.push("сыр");            // добавить в конец
cart.pop();                 // убрать с конца
cart.unshift("яйца");      // в начало
cart.indexOf("хлеб");       // индекс 1 или -1
cart.join(", ");            // "яйца, хлеб, молоко"
cart.includes("молоко");   // true
ℹ️
Короткое «правда ли, что»: push, pop, shift, unshift меняют массив как есть, а map, filter, slice возвращают новый.

console: красивые выводы

В консоли можно наводить красоту и структуру — это здорово ускоряет отладку:

console.log("Обычное сообщение");
console.warn("Предупреждение");
console.error("Что-то сломалось");

const users = [{ name: "Аня" }, { name: "Петя" }];
console.table(users);      // удобная табличка в консоли

console.log("Пользователь:", users[0]);  // объект раскроется интерактивно
💡
console.table() для массивов объектов — лучший друг: сразу видно все поля разом, столбцами.

null, undefined и NaN

Три «странных» значения JS преследуют новичков. Разберёмся раз и навсегда:

let a;                 // undefined
const b = null;        // null
console.log("5" * "x"); // NaN

Number.isNaN(NaN);      // true — правильная проверка NaN
NaN === NaN;            // false! NaN не равен сам себе
💡
NaN === NaN ложно — это особенность стандарта. Когда нужно проверить «не число», всегда используйте Number.isNaN(...).

Многострочные шаблонные строки

Шаблонные строки (обратные кавычки) позволяют писать текст в несколько строк и встраивать выражения без склейки:

const name = "Аня";
const lines = `
Привет, ${name}!
Первая строка.
Вторая строка.
`;

console.log(lines);
// Выведет три строки с подставленным именем.
ℹ️
Внутри ${...} можно класть любое выражение: ${2 + 3}, ${user.name || "Гость"}.

Опциональная цепочка: ?.

Обращение obj?.prop не бросает ошибку, если obj окажется null или undefined:

const user = { profile: { city: "Москва" } };

user.profile?.city;               // "Москва"
user.account?.balance;            // undefined, а не ошибка
user.settings?.theme ?? "light"; // "light", если theme нет
⚠️
Не задавайте пустое через сплошную ?.?.?.? — цепочкой злоупотреблять не стоит. Если поле обязано существовать, отсутствие должно всплыть как ошибка: так её проще поймать.

find, some, every

Три метода для поиска по массиву, которые встречаются в коде на каждом шагу:

const users = [
  { name: "Аня", age: 25 },
  { name: "Петя", age: 17 },
  { name: "Оля", age: 30 }
];

const petya = users.find(u => u.name === "Петя");   // первый совпавший
const hasKids = users.some(u => u.age < 18);      // true — хоть один
const allAdult = users.every(u => u.age >= 18);   // false — не все
💡
find возвращает объект или undefined, some/every — true/false. Индекс находите через findIndex.

== и ===: разница критична

Двойное равно приводит типы, тройное — сравнивает честно:

5 == "5"   // true,  сработало приведение
5 === "5"  // false, типы разные
0 == false // true (фу)
0 === false // false
💡
Только === и !==. Привыкайте сразу — это убережёт от класса неочевидных багов.

Тернарный оператор

Условие в одну строку: условие ? да : нет:

const age = 17;
const label = age >= 18 ? "взрослый" : "несовершеннолетний";
ℹ️
Он не «короче», он читаемее в простом случае. Два уровня вложенности — уже кандидат на if/else.

Логика: && , || , !

И, ИЛИ, «не»: собирайте сложные условия:

const opened  = true;
const weekend = false;

if (opened && !weekend) {
  console.log("Офис открыт");
}
if (opened || user.isCool) {
  console.log("Проходи");
}

switch: множество веток

Сравнение значения с рядом вариантов — бесконечные else if заменяет switch:

switch (status) {
  case "new":
    console.log("Новый заказ");
    break;
  case "done":
    console.log("Готов");
    break;
  default:
    console.log("Другое");
}
⚠️
Забыть break — случайно «провалимся» в следующую ветку. Продумайте проверку каждого case.

Области видимости

Где переменная живёт, зависит от способа объявления:

let a = 1;        // виден в своём блоке
const b = 2;      // то же + переприсваивать нельзя
var c = 3;        // всплывает в функцию (устарел)

if (true) {
  let inner = 5;
}
console.log(inner);  // ReferenceError

Ловушка дробей

Компьютер хранит числа в двоичной системе, поэтому 0.1 + 0.2 ≠ 0.3:

console.log(0.1 + 0.2);   // 0.30000000000000004

const sum = (0.1 + 0.2).toFixed(2);  // "0.30"
ℹ️
Для денег используйте целые копейки или библиотеки денег — иначе проценты «накапают» сюрпризами.

Math: округление и случайность

Полезные методы встроенного объекта Math:

Math.round(2.6);   // 3
Math.floor(2.9);   // 2 — вниз
Math.ceil(2.1);    // 3 — вверх

// случайное целое от 1 до 6:
const dice = Math.floor(Math.random() * 6) + 1;

Форматирование toFixed

Сколько знаков после запятой показывать — решает toFixed:

const price = 19.956;
price.toFixed(2);    // "19.96"
price.toFixed(0);    // "20"

const text = +price.toFixed(2);  // число 19.96

Строки в числа: parseInt и parseFloat

Парсят число с начала строки и игнорируют «хвост»:

parseInt("42px");     // 42 — отбросил px
parseInt(" 7 дней");  // 7 — пробел стёрт
parseFloat("2.5кг");  // 2.5 — дробь
parseInt("abc");      // NaN
ℹ️
Если от строки нужна ТОЛЬКО цифра — сравнивайте: Number("42px") даст NaN, а parseInt — 42. Знайте разницу и выбирайте.

length и доступ к символам

Длина строки и отдельный символ по индексу:

const name = "web";
name.length;      // 3
name[0];          // "w"
name[name.length - 1]; // "b" — последний символ

indexOf и includes

Поиск подстроки в строке:

"hello world".indexOf("world");  // 6
"hello world".indexOf("x");      // -1 — не найдено

"hello".includes("ell");       // true
"hello".startsWith("he");     // true

NaN и Infinity

Особые числа, с которыми всё «странно»:

0 / 0;         // NaN
1 / 0;         // Infinity

Number.isNaN("x" * 2);  // true
// NaN !== NaN, поэтому проверяйте только через Number.isNaN

Инкремент и декремент

Счетчики: ++ и --, и чем они отличаются до/после:

let n = 5;
console.log(n++);   // выведет 5, потом становится 6
console.log(++n);   // сразу 7
💡
В циклах i++ и ++i равнозначны. Осторожнее со «вложенными» выражениями — читабельности ноль.

Дефолт через ||

Классический приём: если слева пусто, берём запасной вариант:

const username = user.name || "Гость";
const price    = rawPrice || 0;

// современный вариант для null/undefined:
const cute = rawCuteness ?? 100;
⚠️
|| сработает и на пустой строке, и на 0. Если такие значения важны как «настоящие» — используйте ?? (только к null/undefined).

Тренировка

  1. Объявите const с вашим именем и let с годом рождения.
  2. Вычислите среднее арифметическое трёх чисел и выведите в консоль.
  3. Создайте массив технологий и выведите вторую из него в консоль.
  4. Соберите приветствие с интерполяцией: Привет, ${имя}!
ℹ️
Консоль разработчика — лучший друг: F12 → вкладка «Console». Там видны и console.log, и ошибки.