Как и какими средствами находить ошибки в Javascript коде?

Алексей Шиманский

Частенько, при разработке, код не работает так, как задумано или вообще не работает. Сижу часами, гадаю: что и где не так?

А порой просто иду на проф. ресурсы, например Stack Overflow и публикую вопрос "Где здесь ошибка?" или "Почему не работает?"

В итоге часто проблема мелкая, дурацкая опечатка, ошибка в синтаксисе и прочее. Профессионалом так не станешь, если по каждой ерунде бегать по ресурсам. А я хочу им быть.

Вопрос: какие есть способы, чтобы найти ошибки в Javascript коде? Какие инструменты, методы, плагины, пути и пр.?

3 ответа

Алексей Шиманский

Вчера всё работало, а сегодня не работает / Код не работает как задумано

или

Debugging (Отладка)

В чем заключается процесс отладки? Что это такое?

Процесс отладки состоит в том, что мы останавливаем выполнения скрипта в любом месте, смотрим, что находится в переменных, в функциях, анализируем и переходим в другие места; ищем те места, где поведение отклоняется от правильного.

Будет рассмотрен пример с Сhrome, но отладить код можно и в любом другом браузере и даже в IDE.

Открываем инструменты разработчика. Обычно они открывается по кнопке F12 или в меню ИнструментыИнструменты Разработчика. Выбираем вкладку Sources

Цифрами обозначены:

  1. Иерархия файлов, подключенных к странице (js, css и другие). Здесь можно выбрать любой скрипт для отладки.
  2. Сам код.
  3. Дополнительные функции для контроля.

В секции №2 в левой части на любой строке можно кликнуть ЛКМ, тем самым поставив точку останова (breakpoint - брейкпойнт). Это то место, где отладчик автоматически остановит выполнение JavaScript, как только до него дойдёт. Количество breakpoint'ов не ограничено. Можно ставить везде и много. На изображении выше отмечен зеленым цветом.

В остановленном коде можно посмотреть текущие значения переменных, выполнять различные команды и др.

А во вкладке Breakpoints можно:

  • На время выключить брейкпойнт(ы)
  • Удалить брейкпойнт(ы), если не нужен
  • Быстро перейти на место кода, где стоит брейкпойнт кликнув на текст.

Запускаем отладку

В данном случае, т.к. функция выполняется сразу при загрузке страницы, то для активации отладчика достаточно её перезагрузить. В ином случае, для активации требуется исполнить действие, при котором произойдет исполнение нужного участка кода (клик на кнопку, заполнение инпута данными, движение мыши и другие действия)

В данном случае после перезагрузки страницы выполнение "заморозится" на 4 строке:

  • Вкладка Watch — показывает текущие значения любых переменных и выражений. В любой момент здесь можно нажать на +, вписать имя любой переменной и посмотреть её значение в реальном времени. Например data или nums[0], а можно и nums[i] и item.test.data.name[5].info[key[1]] и т.д.

  • Вкладка Call Stack — стэк вызовов, все вложенные вызовы, которые привели к текущему месту кода. На данный момент отладчик стоит в функции getSum, 4 строка.

  • Вкладка Scope Variables — переменные. На текущий момент строки ниже номера 4 ещё не выполнилась, поэтому sum и output равны undefined.

В Local показываются переменные функции: объявленные через var и параметры. В Global – глобальные переменные и функции.

Процесс

Для самого процесса используются элементы управления (см. изображение выше, выделено зеленым прямоугольником)

(F8) — продолжить выполнение. Продолжает выполнения скрипта с текущего момента. Если больше нет других точек останова, то отладка заканчивается и скрипт продолжает работу. В ином случае работа прерывается на следующей точке останова.

(F10) — делает один шаг не заходя внутрь функции. Т.е. если на текущей линии есть какая-то функция, а не просто переменная со значением, то при клике данной кнопки, отладчик не будет заходить внутрь неё.

(F11) — делает шаг. Но в отличие от предыдущей, если есть вложенный вызов (например функция), то заходит внутрь неё.

(Shift+F11) — выполняет команды до завершения текущей функции. Удобна, если случайно вошли во вложенный вызов и нужно быстро из него выйти, не завершая при этом отладку.

— отключить/включить все точки останова

— включить/отключить автоматическую остановку при ошибке. Если включена, то при ошибке в коде он скрипт остановится автоматически и можно посмотреть в отладчике текущие значения переменных, проанализировать и принять меры по устранению.

...

Итак, в текущем коде видно значение входного параметра:

  • data = "23 24 11 18" — строка с данными через пробел
  • nums = (4) ["23", "24", "11", "18"] — массив, который получился из входной переменной.

Если нажмем F10 2 раза, то окажемся на строке 7; во вкладках Watch, Scope > Local и в самой странице с кодом увидим, что переменная sum была инициализирована и значение равно 0.

Если теперь нажмем F11, то попадем внутрь функции-замыкания nums.forEach

Нажимая теперь F10 пока не окончится цикл, можно будет наблюдать, как на каждой итерации цикла постоянно изменяются значения num и sum. Тем самым мы можем проследить шаг за шагом весь процесс изменения любых переменных и значений на любом этапе, который интересует.

Дальнейшие нажатия F10 переместит линию кода на строки 11, 12 и, наконец, 15.

Дополнительно

  • Остановку можно инициировать принудительно без всяких точек останова, если непосредственно в коде написать ключевое слово debugger:

    function getSum(data) {
      ...
      debugger; // <-- отладчик остановится тут
      ...
    }
  • Если нажать ПКМ на строке с брейкпойнтом, то это позволит еще более тонко настроить условие, при котором на данной отметке надо остановиться. В функции выше, например, нужно остановиться только когда sum превысит значение 20.

    Это удобно, если останов нужен только при определённом значении, а не всегда (особенно в случае с циклами).

Больше информации о возможностях инструментов например Chrome — можно прочитать здесь

Дополнительно 2

Принудительную отладку можно инициировать событием, происходящим на странице/элементах. Это полезно, если не знаешь где обрабатывающая функция находится.

Пример для Chrome:

Нажимаем F12, заходим на вкладку Sources и в функциях контроля видим вкладку Event Listener Breakpoints, в которой можно назначить в качестве триггера любые события, при которых исполнение скрипта будет остановлено. На изображении ниже выбран пункт на событие onchange элементов.

Для Firefox:

Если функция инлайновая, например

то можно зайти в Инспектор, найти тот самый элемент, в котором прописано событие и обнаружить рядом значок em:

Кликнув на него, как утверждает developer.mozilla.org/ru/docs можно увидеть строчки:

где можно увидеть события, навешанные на элемент, скрипт, строку, возможность нажать на паузу и т.д.

В других случаях, а также если кнопка паузы не обнаружена, то на вкладке Debugger(отладчик) надо найти стрелку, при наведении на которую будет написано "Events". Там должно быть событие выделенного элемента.

А вот таких полезных вкладок как у Chrome к сожалению у Firefox там нет.


Алексей Шиманский

Консоль разработчика

Если код "шалит", не работает — открываем инструменты разработчика, которые имеются в любом браузере. Обычно они открывается по кнопке F12 или в меню ИнструментыИнструменты Разработчика. Выбираем вкладку Console

Поведение её примерно такое же как в IDE - она выводит красным цветом:

  • причину ошибки
  • полный текст ошибки
  • имя скрипта с ошибкой
  • номер строки в том самом скрипте

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

Не знаете английский?

Откройте любой онлайн переводчик и скопируй туда текст ошибки заменив заглавные буквы на строчные:

uncaught syntax error: unexpected token )

Непонятная синтаксическая ошибка: неожиданный токен(символ) )

Прям русским языком говорит: ошибка в синтаксисе. Значит и искать надо в указанном направлении.


Алексей Шиманский

Дедовский способ

Не смотря на описанный ниже способ, нужно сразу отметить, что есть замечательные инструменты, которые быстрее помогут обнаружить и исправить ошибки. Одним из них является Интегрированная среда разработки (IDE). Более подробно о ней можно прочитать в вопросе:

Какие есть способы предупреждения ошибок, их нахождения и устранения?

О способе.

Сам способ использовался еще когда не было умных сред разработок и как раз писали код, по-сути, в блокнотах. Сейчас он тоже работает, хотя при наличии умных сред разработок и отладчиков — это не самый быстрый и эффективный способ. Используется alert.

Алгоритм действий:

  1. Пишешь alert('ЛЮБАЯ_ТЕСТОВАЯ_ФРАЗА') в, например, середину скрипта, всё что ниже - комментируется! Перезагружается страница.
  2. Если alert не появился — значит ошибка выше. Удаляем и пишем его выше, всё что ниже - комментируется!
  3. Если надпись появилась, значит проблема ниже. Удаляем и пишем его ниже
  4. Повторяем шаги 2 и(или) 3 пока не найдем ошибку.

Пример: Код ниже не запускается

var test1 = 1;
var test2 == 2;
var result = test1 + test2;
alert(result);

Ожидаем увидеть 3, но не видим вообще ничего. Значит, где-то имеется синтаксическая ошибка. Поставим alert повыше, всё что ниже - комментируется!

var test1 = 1;
var test2 == 2;
alert('работает или нет?');
/*
var result = test1 + test2;    
alert(result);
*/

Не работает. Поставим выше.

var test1 = 1;
alert('работает или нет?');
/*
var test2 == 2;        
var result = test1 + test2;    
alert(result);
*/

Появилась надпись. Значит проблема была в строке ниже. Если присмотреться, видно, что поставили случайно вместо знака присваивания — знак равно.

var test2 == 2; 
           ^------- лишний знак

Исправляем.

licensed under cc by-sa 3.0 with attribution.