Поиск багов является неотъемлемой частью разработки любой сложной программы. Данный процесс называется отладкой, или дебаггингом. В большинстве случаев для поиска багов достаточно метода console.log, где вы будете выводить различные сообщения, значения переменных и т.д., которые позволят вам понять, что не так с вашим приложением. Но бывают случаи, когда найти баг не так-то просто, и не просто даже понять в какой части кода искать баг.
В таких случаях вам поможет встроенный функционал браузера, для поиска багов. И чтобы этим функционалом пользоваться вам надо в коде написать ключевое слово debugger. Данное ключевое слово называется точкой останова, и говорит браузеру в каком месте остановить выполнение кода и запустить функционал отладчика. Давайте напишем его в самом начале нашего кода JavaScript. Т.е. как только транслятор захочет начать выполнение кода, то он сразу же остановится.

Запускаем нашу страницу. Открываем консоль, перезагружаем.

Как видите, транслятор остановил выполнение кода на ключевом слове дебаггер, и у нас не вывелись задачи в списке. Также в окне сайта появилось сообщение, что выполнение кода остановилось в отладчике. Рядом с этим сообщением нам доступны две кнопки, это запустить наш код от точки остановы до конца, или выполнить текущую строку, перейти к следующей строке и снова остановиться.
Давайте сперва нажмём на выполнить код от точки останова до конца. И наш список загрузился. Снова обновим страницу и нажмем на кнопку StepOver, что переводится как перешагнуть через. И как видим транслятор теперь остановился на следующей строке. Выполнив предыдущую. Ну в ключевом слове debbuger ему ничего выполнять не пришлось, поэтому он просто перешел на следующую строку и остановился.
Теперь взгляните сюда в раздел область действия. Сейчас он состоит из двух пунктов: Сценарий и Глобальные. В разделе сценарий находятся переменные, константы и функции, которые доступны в этом участке кода и не являются частью глобального объекта window. Т.е. это переменные, константы и функции, объявленные с помощью ключевых слова let и const.
Как видите в разделе скрипт у нас три константы. Но пока еще никаких значений у них нет, так как транслятор не выполнил эти строки. Нажмем на кнопку StepOver. И он выполнил эту строчку кода и остановился на этой. В области видимости у первой константы появилось значение. Это DOM объект. Здесь очень удобно, что мы можем с помощью этого треугольника посмотреть на все свойства данного объекта. Выполним следующие две строчки.
Далее транслятор прикрепляет слушатель к кнопке button.

Двигаемся дальше. Жмем еще раз StepOver. И теперь транслятор прикрепляет слушатель к всему документу. Но копа его не выполняет, так как пока транслятор не добрался ещё до конца нашего кода. Затем если мы еще раз нажмем на StepOver, то транслятор покажет, что он добрался до конца кода, и теперь ждет, когда запустится та или иная функция в слушателях, а у нас должна запустится функция внутри слушателя всего документа.
Нажимаем на StepOver. И вот запустился слушатель где транслятор выполняет первую строчу в теле функции. И так как мы находимся внутри функции, у которой есть свои локальные переменные, константы и функции, у нас появился новый раздел в области видимости – это Локально. Здесь отображаются переменные константы и функции, которые видны только внутри этой функции. Также мы можем увидеть чему равно ключевое слово this в этой функции, это тоже очень удобно. Так как данная строчка еще не выполнилась, то константа savedTasks пока не имеет значения.
Нажимаем на stepOver, теперь транслятор переходит к следующей строке. И у SavedTask теперь появилось значение в виде массива. Дальше у нас идет строчка кода, где мы обрабатываем каждый элемент массива. И для транслятора – это вся одна строчка где мы вызываем метод forEach для массива saveTask. Так как вот этот весь код находится внутри метода forEach, то транслятор воспринимает это все как одну строчку. Т.е. если мы сейчас нажмем на StepOver, то транслятор просто выполнит весь этот код, т.е. добавит все задачи на сайте.
Так мы ошибку не найдем. Нам надо, чтобы транслятор показал, как он будет выполнять каждую строчку внутри этого метода.
И здесь нам надо обратить внимание на эту панель с кнопками. Где первые две – это аналогичные кнопки этим двум кнопками – т.е. запустить код и степ овер.
Далее, если внутри строки мы вызываем функцию или метод, то кнопка Step Into позволяет увидеть вам как транслятор будет выполнять код внутри этой функции или метода. Т.е. если мы сейчас нажмем на Step Into то мы переместимся внутрь тела этого метода. А за тело этого метода будет отвечать эта стрелочная функция, т.е. мы автоматически перейдем в тело этой стрелочной функции. Нажимаем. И мы перемещаемся в тело метода forEach. Далее мы также можем перемещаться с помощью Step Over по этим строчкам. Транслятор воспринимает код внутри if как отдельные строчки, ко которым stepOver будет проходится. если условие if будет истинным.
Давайте это проверим.
Как видите транслятор выполнил функцию addTask и добавил первую задачу на сайт. В этой задаче Complited равен false. И транслятор, после проверки условия, не будет выполнять код внутри условного оператора if. Нажимаем на step over. Транслятор показывает, что завершил выполнение первой итерации forEach. Нажимаем снова stepOver, и мы попадем на вторую итерацию. Снова StepOver. Добавилась новая задача. И здесь Completed будет равен true, а значит транслятор выполнит весь код внутри if. Нажимает. И как видите появилась еще одна область видимости – блок. Т.е. здесь будут переменные, константы и функции, которые видны только внутри этого блока if. В этой строчке мы получаем все теги ли которые есть. А их всего два. Нажимаем step over. Далее внутри этого forEch мы выберем тот тег ли, где текст равен текущей задаче, и в этом теге ли зачеркнем текст задачи и поставим галочку на чекбоксе. Завершили эту Итерацию. Переходим к следующей.
Как помните, если в строке есть вызов функции, то мы можем перейти к этой функции с помощью stepInto, давайте нажмем. Теперь мы можем увидеть как выполняется код внутри AddTask. Давайте чуть пробежимся, здесь с помощью кнопки StepOver. И мы переместились к последней строчке в теле функции addTask. Получается до этой строчки мы добавили задачу, а теперь на этой строчке мы сохраняем результат в память. Это ключевой момент. Запомните его. Нажимаем степ овер, и транслятор покажет что он завершает эту функцию. Нажимаем еще раз и мы перемещаемся снова внутрь итерации фор ич. Здесь также сработает код внутри if, а значит добавится и зачеркивание. Но ничего пока мы не сохраняем. Переходим к следующей итерации.
Изучим теперь следующую кнопку, это Step Out, которая позволяет выйти нам из текущей функции. Давайте сперва зайдем в функцию AddTask. Пройдемся по строчкам этой функции, и вот мы узнали что нам было нужно в этой функции, и не хотим двигаться дальше, а хотим выйти из нее, для этого и нужна кнопка StepOut. Нажимаем, и так мы выходим из функции AddTask. Но мы помним, что после того как функция addTask сработала, то у нас произошло сохранение. Т.е. сохранилась не только новая задача Заправить кровать, но и то что эта задача была выполнена.
Но теперь что происходит на последней задаче. Представим, что у нее комплитед тру в памяти. Транслятор выполнит этот код, зачеркнет текст, поставит галочку, но не сохранит результат в память. Поэтому при следующей перезагрузке странице, в памяти не будет информации что эта задача выполнена, поэтому она отобразится как не зачеркнутая и без галочки.
Как это исправить? Нам просто надо добавить строчку с сохранением данных как последнюю строчку в блоке if.
Кстати, пока мы не исправили, я расскажу зачем нужны эти конопки. Эта называется шаг, проходится абсолютно по всем строчкам кода, которые выполняет транслятор, независимо, где они находятся. По сути это смесь StepOver и StepIn, который покажет все строчки кода, который выполнит браузер.
А с помощью этой кнопки транслятор может не реагировать на точку останова. Т.е. браузер при следующей перезагрузке страницы проигнорирует точку останова. Давайте нажмем на неё.
Осталось исправить баг в программе. Копируем вызов функции для сохранения и вставляем сюда. Проверяем. Теперь все работает. На этом урок заканчивается. До встречи на следующих уроках.