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

Когда вы создали игру «Угадай номер» в предыдущей статье, вы, возможно, обнаружили, что она не работает. Не бойтесь — эта статья призвана избавить вас от разрыва волос над такими проблемами, предоставив вам несколько простых советов о том, как найти и исправить ошибки в программах JavaScript.

Нужно:

базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое JavaScript.
Цель получить способность и уверенность в том, чтобы приступить к исправлению простых проблем в вашем собственном коде.

Типы ошибок

Когда вы делаете что-то не так в коде, есть два основных типа ошибок, с которыми вы столкнетесь:

  • Синтаксические ошибки: Это орфографические ошибки в коде, которые фактически заставляют программу вообще не запускаться, или перестать работать на полпути — вам также будут предоставлены некоторые сообщения об ошибках. Обычно они подходят для исправления, если вы знакомы с правильными инструментами и знаете, что означают сообщения об ошибках!

  • Логические ошибки: Это ошибки, когда синтаксис действительно правильный, но код не тот, каким вы его предполагали, что означает, что программа работает успешно, но дает неверные результаты. Их часто сложнее находить, чем синтаксические ошибки, так как обычно не возникает сообщение об ошибке, которое направляет вас к источнику ошибки.

Ладно, все не так просто — есть и другие отличия, которые вы поймете, пока будете изучать язык JavaScript глубже. Однако вышеуказанной классификации достаточно на раннем этапе вашей карьеры. Мы рассмотрим оба эти типа в дальнейшем.

Ошибочный пример

Чтобы начать работу, давайте вернемся к нашей игре с угадыванием чисел — за исключением того, что мы будем изучать версию с некоторыми преднамеренными ошибками. Перейдите в Github и сделайте себе локальную копию number-game-errors.html (см. здесь как это работает).

  1. Чтобы начать работу, откройте локальную копию внутри вашего любимого текстового редактора и вашего браузера.
  2. Попробуйте сыграть в игру — вы заметите, что когда вы нажимаете кнопку «Submit guess», она не работает!

Примечание: Возможно, у вас может быть собственная версия игрового примера, которая не работает, которую вы можете исправить! Мы по-прежнему хотели бы, чтобы вы работали над статьей с нашей версией, чтобы вы могли изучать методы, которые мы здесь преподаем. Затем вы можете вернуться и попытаться исправить ваш пример.

На этом этапе давайте рассмотрим консоль разработчика, чтобы увидеть, можем ли мы видеть какие-либо синтаксические ошибки, а затем попытаемся их исправить. Вы узнаете, как это сделать, ниже.

Исправление синтаксических ошибок

Раньше в курсе мы заставили вас набрать некоторые простые команды JavaScript в консоль разработчика JavaScript (если вы не можете вспомнить, как открыть это в своем браузере, следуйте предыдущей ссылке, чтобы узнать, как это сделать). Что еще более полезно, так это то, что консоль предоставляет вам сообщения об ошибках всякий раз, когда существует синтаксическая ошибка внутри JavaScript, которая подается в механизм JavaScript браузера. Теперь пойдем на охоту.

  1. Перейдите на вкладку, в которой у вас есть number-game-errors.html, и откройте консоль JavaScript. Вы должны увидеть сообщение об ошибке в следующих строках:
  2. Это довольно простая ошибка для отслеживания, и браузер дает вам несколько полезных бит информации, которые помогут вам (скриншот выше от Firefox, но другие браузеры предоставляют аналогичную информацию). Слева направо, у нас есть:
    • Красный «x» означает, что это ошибка.
    • Сообщение об ошибке, указывающее, что пошло не так: «TypeError: guessSubmit.addeventListener не является функцией»
    • Ссылка «Узнать больше», которая ссылается на страницу MDN, которая объясняет, что эта ошибка означает в огромных количествах деталей.
    • Имя файла JavaScript, который ссылается на вкладку «Отладчик» консоли разработчика. Если вы перейдете по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.
    • Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.
  3. Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдем эту строку:
    guessSubmit.addeventListener('click', checkGuess);
  4. В сообщении об ошибке говорится, что «guessSubmit.addeventListener не является функцией», поэтому мы, вероятно, где-то ошиблись. Если вы не уверены в правильности написания синтаксиса, часто бывает полезно найти функцию на MDN. Лучший способ сделать это в настоящее время — поиск «mdn имя-функции» в вашей любимой поисковой системе. Вот ссылка, которая поможет сократить вам некоторое время в данном случае: addEventListener().
  5. Итак, глядя на эту страницу, кажется, что ошибка в том, что мы неправильно назвали имя функции! Помните, что JavaScript чувствителен к регистру, поэтому любые незначительные отличия в орфографии или регистре текста могут вызвать ошибку. Изменение этого параметра в addEventListener должно быть исправлено. Сделайте это сейчас.

Примечание: См. наш TypeError: «x» не является справочной страницей функций для получения дополнительной информации об этой ошибке.

Синтаксические ошибки: второй раунд

Примечание: console.log() это часто используемая функция отладки, которая выводит значение в консоль. Поэтому она будет выводить значение lowOrHi в консоли, как только мы попытаемся установить его в строке 48.

  1. Сохраните и обновите страницу, и вы увидите, что ошибка исчезла.
  2. Теперь, если вы попробуете ввести значение и нажать кнопку "Submit guess", вы увидите ... другую ошибку! 
  3. На этот раз сообщается об ошибке: "TypeError: lowOrHi is null", в строке 78.
    Примечание: Null — это специальное значение, которое означает "ничего" или "не значение". Поэтому lowOrHi был объявлен и инициализирован без значения — у него нет типа или значения.
    Примечание: Эта ошибка не появилась, как только страница была загружена, потому что эта ошибка произошла внутри функции (внутри checkGuess() { ... } block). Об этом вы узнаете более подробно в нашей более поздней статье о функциях, код внутри функций выполняется в отдельной области для кода внешних функций. В этом случае код не был запущен, и ошибка не была брошена до тех пор, пока функция checkGuess() не была запущена строкой 86.
  4. Посмотрите на строку 78, и вы увидите следующий код:
    lowOrHi.textContent = «Последнее предположение было слишком высоко!»;
  5. Эта строка пытается установить свойство textContent переменной lowOrHi как текстовую строку, но это не работает, поскольку lowOrHi не содержит того, что должна. Давайте посмотрим, почему так происходит — попробуйте найти другие экземпляры lowOrHi в коде. Самый ранний экземпляр, который вы найдете в JavaScript, находится в строке 48:
    var lowOrHi = document.querySelector('lowOrHi');
  6. На этом этапе мы пытаемся заставить переменную содержать ссылку на элемент документа HTML. Давайте проверим, является ли значение  null после выполнения этой строки. Добавьте следующий код в строку 49:
    console.log(lowOrHi);
    
  7. Сохраните и обновите, и вы должны увидеть результат работы console.log() в консоли браузера. Разумеется, значение lowOrHi на данный момент равно null, поэтому определенно существует проблема в строке 48.
  8. Давайте подумаем о том, что может быть проблемой. Строка 48 использует метод document.querySelector() для получения ссылки на элемент, выбирая его с помощью селектора CSS. Посмотрев далее наш файл, мы можем найти обсуждаемый элемент <p>:
    <p class="lowOrHi"></p>
    
  9. Поэтому нам нужен селектор классов, который начинается с точки (.), но селектор, передаваемый в метод querySelector() в строке 48, не имеет точки. Возможно, это и есть проблема! Попробуйте изменить lowOrHi на .lowOrHi в строке 48.
  10. Повторите попытку сохранения и обновления, и ваш вызов console.log() должен вернуть элемент <p>, который мы хотим. Уф! Еще одна ошибка исправлена! Вы можете удалить строку с  console.log() сейчас, или оставить для дальнейшего применения — выбирайте сами.

Примечание: Загляните на справочную страницу TypeError: "x" is (not) "y", чтобы узнать больше об этой ошибке.

Синтаксические ошибки: третий раунд

  1. Теперь, если вы снова попробуете сыграть в игру, вы должны добиться большего успеха — игра должна играть абсолютно нормально, пока вы не закончите игру, либо угадав нужное число, либо потеряв жизни.
  2. На данном этапе игра снова слетает, и выводится такая же ошибка, как и в начале — "TypeError: resetButton.addeventListener is not a function"! Однако, теперь она происходит из-за строки 94.
  3. Посмотрев на строку 94, легко видеть, что здесь сделана такая же ошибка. Нам просто нужно изменить addeventListener на addEventListener.

Логическая ошибка

На этом этапе игра должна проходить отлично, однако, поиграв несколько раз, вы, несомненно заметите, что случайное число, которое вы должны угадать, всегда 0 или 1. Определенно не совсем так, как мы хотим, чтобы игра была разыграна!

Безусловно, где-то в игре есть логическая ошибка — игра не возвращает ошибку, она просто работает неправильно.

  1. Найдем переменную randomNumber , и строку где в первый раз устанавливали случайное число. Пример, в котором мы храним случайное число, которое должны угадать, на строке 44:
    var randomNumber = Math.floor(Math.random()) + 1;
    
    И на строке 113, где мы генерируем случайное число, каждый раз после окончания игры:
    randomNumber = Math.floor(Math.random()) + 1;
    
  2. Чтобы проверить, действительно ли проблема в этом, давайте обратимся к нашему другу console.log() снова — вставьте ее ниже строк с ошибками:
    console.log(randomNumber);
    
  3. Сохраните и обновите, а дальше попробуйте пару раз сыграть — в консоли вы увидите что randomNumber равна 1 в каждой точке, где вы ее записали после строк с ошибками.

Работаем через логику

Чтобы исправить это, давайте рассмотрим как работает строка. Первое, мы вызываем Math.random(), котрый генерирует случайное десятичное число, между 0 и 1, например 0.5675493843.

Math.random()

Дальше, мы передаем результат вызова Math.random() через Math.floor(), который округляет число вниз, до ближайшего целого числа. Затем мы добавляем 1 к данному результату:

Math.floor(Math.random()) + 1;

Округление случайного десятичного числа к меньшему, всегда будет возвращать 0, так что добавление к нему единицы будет возвращать всегда 1.  Нам нужно умножить случайное число на 100, прежде чем мы округлим его к меньшему. Следующая строка вернет нам случайное число между 0 и 99:

Math.floor(Math.random() * 100);

поэтому нам нужно добавить 1, чтоб нам возвращалось случайное число между 1 и 100:

Math.floor(Math.random() * 100) + 1;

А теперь, исправьте обе строки с ошибками, затем сохраните и обновите, игра должна работать так, как мы и планировали!

Другие распространенные ошибки

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

SyntaxError: отсутствует ; перед постановкой

Эта ошибка обычно означает что вы упустили точку с запятой в конце одной из ваших строк кода, но иногда ошибка может быть более загадочной. Например, если мы изменим эту строку внутри функции checkGuess() :

var userGuess = Number(guessField.value);

на эту

var userGuess === Number(guessField.value);

Это вызовет данную ошибку, потому что браузер подумает, что вы пытались сделать что-то другое. Вы должны быть уверены, что вы не перепутали оператор присваивания (=), который присваивает значение переменной — с оператором сравнения (===), который строго сравнивает операнды, и возвращает true/false .

Примечание: Загляните на справочную страницу Синтаксическая ошибка: пропущен символ ; до объявления инструкции для получения дополнительной информации об этой ошибке.

В программе всегда говорится, что вы выиграли, независимо от того, что вы ввели

Причиной этому является все то же перепутывание оператора присваивания (=) со строгим сравнением (===). Например, если мы изменим внутри checkGuess() эту строку кода:

if (userGuess === randomNumber) {

на эту

if (userGuess = randomNumber) {

мы всегда будем получать true, заставляя программу сообщать, что игра была выиграна. Будьте осторожны!

SyntaxError: отсутствует ) после списка аргументов

Эта ошибка проста — обычно она означает, что вы пропустили закрывающую скобку с конца вызова функции / метода.

Примечание: Загляните на справочную страницу  SyntaxError: missing ) after argument list для получения дополнительной информации об этой ошибке.

SyntaxError: отсутствует : после идентификатора недвижимости

Эта ошибка обычно связана с неправильно сформированным объектом JavaScript, но в этом случае нам удалось получить ее, изменив

function checkGuess() {

на

function checkGuess( {

Это заставило браузер думать, что мы пытаемся передать содержимое функции в функцию в качестве аргумента. Будьте осторожны с этими скобками!

SyntaxError: отсутствует } после того, как тело функции

Это легко — обычно это означает, что вы пропустили одну из ваших фигурных скобок из функции или условной структуры. Мы получили эту ошибку, удалив одну из закрывающих фигурных скобок возле нижней части функции  checkGuess().

SyntaxError: ожидается выражение, получил « строку » или SyntaxError: незавершенная строка

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

При всех этих ошибках действуйте так, как в наших  примерах, которые мы рассмотрели в пошаговом руководстве. Когда возникает ошибка, посмотрите полученный номер строки, перейдите к этой строке и посмотрите, можете ли вы определить, что случилось. Имейте в виду, что ошибка не обязательно будет на этой строке, а также, что ошибка может быть вызвана не такой же проблемой, которую мы привели выше!

Примечание : Смотрите наш SyntaxError: Неожиданный токен и SyntaxError: незавершенная строка эталонных страниц для получения более подробной информации об этих ошибках.

Резюме

Итак, мы научились основам  выяснения ошибок в простых программах JavaScript. Не всегда так просто разобраться, что не так в вашем коде, но, по крайней мере, это сэкономит вам несколько часов сна и позволит вам продвигаться немного быстрее, когда что-либо заработает не так, как ожидалось, в вашем учебном путешествии.

Смотрите также

  • Есть много других типов ошибок, которые не перечислены здесь; мы составляем ссылку , которая объясняет , что они означают подробно - см. ссылку ошибки JavaScript .
  • Если вы столкнетесь с любыми ошибками в коде, которые вы не знаете , как исправить после прочтения этой статьи, вы можете получить помощь! Спросите на нить обучения Область дискурсе , или в #mdn IRC канал на Mozilla IRC. Расскажите нам, какая у вас ошибка, и мы постараемся вам помочь. Приложите пример своего кода для большей ясности проблемы.

Метки документа и участники

Внесли вклад в эту страницу: chrisdavidmills, SedovDP, ArturWer, hasiev-elchin, Froris, AliyevHrn, MariyaSka, AndrewSamofalov, SergeySM, nikitapoly
Обновлялась последний раз: chrisdavidmills,