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

371
04 августа 2017, 02:51

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

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

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

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

Answer 1

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

или

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.

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

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

Answer 2
IDE и Дедовский способ IDE!

Это, конечно, прекрасно играть в ТРУ программиста и писать весь код в блокноте, но так уже никто не делает. На дворе 2017 и все используют IDE (англ. Integrated Development Environment - Интегрированная среда разработки).

Их очень много: WebStorm, NetBeans, Eclipse, Brackets, Sublime и пр. У них бесконечные возможности, например:

  • детектор дублируемого кода
  • рефакторинг
  • интеграция с системами управления версиями
  • автодополнение кода
  • подсветка синтаксиса
  • подсказки при наборе кода (функции, ключевые слова, переменные, которые объявлял ранее)
  • и многое другое

Как это поможет?

Среда знает, что она редактирует код и знает язык, на котором написан код. В неё встроен синтаксический анализатор языка программирования.

Еще на самом первом этапе написания кода она может показать строки с банальными (и не только) ошибками, но которые уже могут привести к нерабочему или неправильно функционирующему коду. 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; 
           ^------- лишний знак    

Исправляем.

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

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

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

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

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

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

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

uncaught syntax error: unexpected token )

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

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

READ ALSO
DataRange на js

DataRange на js

Задача создать компонент, представляющий собой два инпута выбора дат, для установки промежутка времениБез фреймворков

537
Как оптимизировать AJAX запрос?

Как оптимизировать AJAX запрос?

Есть два связанных option поля в форме для фильтрации автомобилей по маркам и моделям: mark -> modelПри выборе марки подгружаются модели

292
Подгрузка html шаблона

Подгрузка html шаблона

Подскажите как правильно организовать загрузку html файла средствами jsТ

262
Бесконечный перебор массива

Бесконечный перебор массива

Дан цикл с большим количеством итерацийДан массив с четырьмя элементами

588