Первая часть: знакомство с отладчиком
Вторая часть: узнаём значение переменной без console.log
Стек вызовов
Продолжаем отладку приложения со списком дел. В этот раз будем чинить удаление задач. Откройте приложение в новой вкладке. Эта версия тоже сломана нарочно, чтобы мы разобрались, что такое стек вызовов.
Как откроете приложение, добавьте несколько своих задач в список дел. Затем удалите первую в списке задачу. Кнопка Delete. Пока всё работает. Теперь удалите последнюю в списке задачу. Опачки! Почему-то удалилась первая. Если не заметили, попробуйте снова: удалите любую задачу, кроме первой. То же самое! Какую бы задачу мы не удаляли, пропадает первая в списке.
Вы знаете, что делать: открываем инструменты разработчика, затем отладчик. Нас интересует функция removeSingle
, файл app.js
, 39-я строка. Именно эта функция отвечает за удаление задач из списка.
Поставим точку останова на 40-й строке. Попробуйте теперь удалить любую задачу из списка, кроме первой. Сработает точка останова, и мы сможем построчно выполнять код, чтобы найти ошибку.
В прошлой статье мы использовали кнопку навигации «Перешагнуть через», чтобы найти ошибку. Мы можем воспользоваться ей снова, но особенность этой кнопки в том, что код выполняется построчно целиком. Даже если это вызов функции. А что, если ошибка «прячется» в этой функции?
Что, если проблема не в removeSingle
, а в spliceItem
? В этом случае выручит кнопка «Зайти в»:
Кнопка «Зайти в» позволяет «провалиться» в функцию вместо её вызова целиком и отладить её код тоже.
После остановки на 40-й строке нажимайте «Зайти в» до тех пор, пока не окажетесь на 24-й строке, внутри функции createList
. Если вы не поймёте, как там оказались, ничего страшного. Разберёмся!
Функция createList
принимает массив list
с данными для отрисовки списка задач. Давайте посмотрим на его элементы. Наведите курсор на параметр list
или загляните в блок «Области видимости».
В массиве с данными вы найдёте задачу, которую удалили. Значит, в функцию createList
передана неверная информация. Но в самой функции ошибки нет, она где-то раньше.
Обратимся к панели инструментов отладчика, та что справа. В блоке «Стек вызовов» можно найти список всех вызванных функций до момента остановки. Кроме названия функции, там указаны номер строки и имя файла, где функция была вызвана. Количество функций говорит о размере стека. Выделение показывает, как глубоко мы в стеке.
В нашем случае стек глубиной в четыре вызова. Точка останова в функции removeSingle
. Затем мы «провалились» в spliceItem
, после в saveList
и вот мы в createList
:
По стеку можно перемещаться. Для этого достаточно кликнуть по нужной функции в списке.
Чтобы найти ошибку, прогуляемся по стеку. Кликнем по функции saveList
. Отладчик перенесёт нас к её объявлению. Это простая, возможно даже лишняя, функция. Она всего лишь вызывает createList
и передаёт ей аргументами глобальные переменные items
и todoList
. Вряд ли ошибка в такой простой функции, поэтому двигаемся дальше.
Кликнем в стеке по функции spliceItem
. Так-так-так... Значение параметра index
не определено. Это уже зацепка!
Подымемся выше, в функцию removeSingle
, чтобы понять, почему в spliceItem
передаётся undefined
. Ошибка где-то здесь:
const index = el.dataset.number;
Наведём курсор на index
, увидим undefined
. Если наведём на number
— то же самое. Тогда давайте посмотрим значение dataset
. Вот оно! В объекте dataset
нет ключа number
. Индекс записан по ключу index
, что логично.
Даже не ошибка, обычная опечатка. Останется только поправить код:
const index = el.dataset.index;
Но исправления уже за рамками нашей статьи... Дело раскрыто.
Совет в тему
В нашем приложении всего десяток функций. Каждая длинной в пару строк. Найти нужную несложно. Но что, если в файле сотня функций? Также искать глазами? Нет! Воспользуйтесь поиском по функциям.
Для поиска нажмите shift + control + O
в Windows и Linux или shift + command + O
в macOS. Далее впишите имя функции, которую хотите найти. Или воспользуйтесь стрелками на клавиатуре для навигации по списку всех функций в приложении.