Ошибки в JavaScript чаще всего чинятся не “угадыванием”, а отладкой: понять, где код оказался не таким, как ожидалось, и почему. Для этого нужны две вещи:
- уметь читать ошибку (сообщение + строка + stack trace)
- уметь остановить выполнение и посмотреть значения (breakpoint, debugger)
1) Как читать ошибку в консоли
Типичное сообщение в DevTools выглядит так:
- тип ошибки (например,
ReferenceError,TypeError) - сообщение (что произошло)
- файл:строка:колонка
- stack trace (цепочка вызовов, как код дошел до ошибки)
Пример:
TypeError: Cannot read properties of null (reading 'textContent')main.js:12
Смысл:
- где-то вызывается
.textContent, но значение слева -null - значит, элемент не найден (
querySelectorвернулnull) или переменная потеряла значение
2) Самые частые типы ошибок и что они означают
ReferenceError
Переменная не объявлена или нет в текущей области видимости.
console.log(count);
TypeError
Операция применяется не к тому типу (часто - вызвали не функцию, или попытались читать свойство у null/undefined).
const el = null;
console.log(el.textContent);
SyntaxError
Синтаксис неверный: пропущена скобка, запятая, кавычка.
const a = ;
3) Stack trace: почему он важнее, чем первая строка кода
Если ошибка возникла глубоко в функции, stack trace покажет путь.
Идея: сверху - место, где ошибка случилась, ниже - кто вызвал, и так далее.
Мини-пример:
function formatUser(user) {
return user.name.toUpperCase();
}
function render(user) {
return formatUser(user);
}
render(null);
Ошибка будет в formatUser, но причина может быть в том, что render передал null.
4) Breakpoints: остановка на нужной строке
Breakpoint - это точка останова в DevTools, где выполнение останавливается и можно посмотреть:
- значения переменных
- call stack
- область видимости (Scope)
- выполнить выражения в Console
Где обычно ставить breakpoint:
- перед строкой, где “что-то стало не так”
- в начале обработчика события
- перед return в функции, которая дает неправильный результат
5) Пошаговое выполнение: step over / step into / step out
Во время остановки доступны действия:
- Step over - выполнить текущую строку и перейти дальше (не заходя внутрь функций)
- Step into - зайти внутрь вызванной функции
- Step out - выйти из текущей функции до места, где она была вызвана
- Resume - продолжить выполнение до следующего breakpoint
Это основной способ понять, на каком шаге переменная получила неожиданное значение.
6) debugger: точка останова прямо в коде
Иногда проще поставить точку останова кодом, особенно если:
- код генерируется
- нужно остановиться внутри условия
- breakpoint трудно поймать
function calcTotal(items) {
let total = 0;
for (const item of items) {
if (item.price < 0) {
debugger;
}
total += item.price;
}
return total;
}
debugger; сработает только когда DevTools открыт. После отладки его обычно удаляют.
7) Watch и проверка выражений
Watch (или “наблюдаемые выражения”) помогает следить за важными значениями, например:
items.lengthuser?.namestate.mode
Если Watch показывает, что значение стало неправильным, легко понять, на каком шаге это произошло, отматывая стек и шаги.
8) Console.log: как использовать в отладке, чтобы не утонуть
console.log полезен, но лучше использовать его как “маркер”, а не как бесконечный поток.
Примеры аккуратных логов:
console.log("loaded items:", items.length);
console.log("minPrice:", minPrice);
console.log("selected id:", id);
Для группировки удобно:
console.group("render");
console.log("items:", items);
console.log("filtered:", filtered);
console.groupEnd();
9) Два типовых сценария: как искать причину
Сценарий A: “ничего не работает” после клика
Обычно ошибка в обработчике события или в DOM-селекторе.
Что делать:
- открыть Console и посмотреть ошибку
- перейти по ссылке
file:line - проверить, что
querySelectorне вернулnull - поставить breakpoint в начале обработчика и пройти шагами
Мини-проверка:
const btn = document.querySelector("#save");
const input = document.querySelector("#name");
btn.addEventListener("click", () => {
console.log("click");
console.log("input:", input);
});
Сценарий B: “данные есть, но отображается неправильно”
Обычно проблема в логике: фильтр, сортировка, преобразование.
Что делать:
- поставить breakpoint перед render
- посмотреть входные данные и результат преобразования
- проверить границы циклов и условия
Пример:
function filterByMin(items, min) {
return items.filter((x) => x.price >= min);
}
Если min - строка, сравнение может вести себя неожиданно. Тогда нужен Number:
const min = Number(input.value) || 0;
10) Что стоит запомнить
- Ошибка в консоли - это карта: тип, сообщение, строка, stack trace.
- Breakpoint и пошаговое выполнение быстрее, чем догадки.
debugger;полезен, когда точку останова удобнее поставить кодом.- Частые причины:
nullвместо элемента,undefinedв данных, строка вместо числа, неправильный путь выполнения.