Learn web development

Что пошло не так? Устранение ошибок JavaScript

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

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

Нужно:

базовая компьютерная грамотность, базовое понимание HTML и CSS, понимание того, что такое 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, который ссылается на вкладку «Отладчик» devtools. Если вы перейдете по этой ссылке, вы увидите точную строку, где подсвечивается ошибка.
    • Номер строки, в которой находится ошибка, и номер символа в этой строке, где первая ошибка. В этом случае у нас есть строка 86, символ номер 3.
  3. Если мы посмотрим на строку 86 в нашем редакторе кода, мы найдем эту строку:
    guessSubmit.addeventListener('click', checkGuess);
  4. В сообщении об ошибке говорится, что «guessSubmit.addeventListener не является функцией», поэтому мы, вероятно, что-то ошиблись. Если вы не уверены в правильности написания синтаксиса, часто бывает полезно найти функцию на MDN. Лучший способ сделать это в настоящее время - поиск «mdn name-of-feature» в вашей любимой поисковой системе. Вот ярлык, который поможет вам некоторое время в этом случае: addEventListener().
  5. Итак, глядя на эту страницу, кажется, что ошибка в том, что мы неправильно назвали имя функции! Помните, что JavaScript чувствителен к регистру, поэтому любые незначительные отличия в орфографии или корпусе могут вызвать ошибку. Изменение этого параметра в addEventListener должно быть исправлено. Сделайте это сейчас.

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

Syntax errors round two

  1. Save your page and refresh, and you should see the error has gone.
  2. Now if you try to enter a guess and press the Submit guess button, you'll see ... another error!
  3. This time the error being reported is "TypeError: lowOrHi is null", on line 78.
    Note: Null is a special value that means "nothing", or "no value". So lowOrHi has been declared and initialised, but not with any meaningful value — it has no type or value.
    Note: This error didn't come up as soon as the page was loaded because this error occurred inside a function (inside the checkGuess() { ... } block). As you'll learn in more detail in our later functions article, code inside functions runs in a separate scope to code outside functions. In this case, the code was not run and the error was not thrown until the checkGuess() function was run by line 86.
  4. Have a look at line 78, and you'll see the following code:
    lowOrHi.textContent = 'Last guess was too high!';
  5. This line is trying to set the textContent property of the lowOrHi variable to a text string, but it's not working because lowOrHi does not contain what it's supposed to. Let's see why this is — try searching for other instances of lowOrHi in the code. The earliest instance you'll find in the JavaScript is on line 48:
    var lowOrHi = document.querySelector('lowOrHi');
  6. At this point we are trying to make the variable contain a reference to an element in the document's HTML. Let's check whether the value is null after this line has been run. Add the following code on line 49:
    console.log(lowOrHi);

    Note: console.log() is a really useful debugging function that prints a value to the console. So it will print the value of lowOrHi to the console as soon as we have tried to set it in line 48.

  7. Save and refesh, and you should now see the console.log() result in your console. Sure enough, lowOrHi's value is null at this point, so there is definitely a problem with line 48.
  8. Let's think about what the problem could be. Line 48 is using a document.querySelector() method to get a reference to an element by selecting it with a CSS selector. Looking further up our file, we can find the paragraph in question:
    <p class="lowOrHi"></p>
  9. So we need a class selector here, which begins with a dot (.), but the selector being passed into the querySelector() method in line 48 has no dot. This could be the problem! Try changing lowOrHi to .lowOrHi in line 48.
  10. Try saving and refreshing again, and your console.log() statement should return the <p> element we want. Phew! Another error fixed! You can delete your console.log() line now, or keep it to reference later on — your choice.

Note: See our TypeError: "x" is (not) "y" reference page for more details about this error.

Syntax errors round three

  1. Now if you try playing the game through again, you should get more success — the game should play through absolutely fine, until you end the game, either by guessing the right number, or by running out of lives.
  2. At the point, the game fails again, and the same error is spat out that we got at the beginning — "TypeError: resetButton.addeventListener is not a function"! However, this time it's listed as coming from line 94.
  3. Looking at line number 94, it is easy to see that we've made the same mistake here. We again just need to change addeventListener to addEventListener. Do this now.

A logic error

At this point, the game should play through fine, however after playing through a few times you'll undoubtedly notice that the "random" number you've got to guess is always 0 or 1. Definitely not quite how we want the game to play out!

There's definitely a problem in the game logic somewhere — the game is not returning an error; it just isn't playing right.

  1. Search for the randomNumber variable, and the lines where the random number is first set. The instance that stores the random number that we want to guess at the start of the game should be around line number 44:
    var randomNumber = Math.floor(Math.random()) + 1;
    And the one that generates the random number before each subsequent game is around line 113:
    randomNumber = Math.floor(Math.random()) + 1;
  2. To check whether these lines are indeed the problem, let's turn to our friend console.log() again — insert the following line directly below each of the above two lines:
    console.log(randomNumber);
  3. Save and refresh, then play a few games — you'll see that randomNumber is equal to 1 at each point where it is logged to the console.

Working through the logic

To fix this, let's consider how this line is working. First, we invoke Math.random(), which generates a random decimal number between 0 and 1, e.g. 0.5675493843.

Math.random()

Next, we pass the result of invoking Math.random() through Math.floor(), which rounds the number passed to it down to the nearest whole number. We then add 1 to that result:

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

Rounding a random decimal number between 0 and 1 down will always return 0, so adding 1 to it will always return 1.  We need to multiply the random number by 100 before we round it down. The following would give us a random number between 0 and 99:

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

Hence us wanting to add 1, to give us a random number between 1 and 100:

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

Try updating both lines like this, then save and refresh — the game should now play like we are intending it to!

Other common errors

There are other common errors you'll come across in your code. This section highlights most of them.

SyntaxError: missing ; before statement

This error generally means that you have missed a semi colon at the end of one of your lines of code, but it can sometimes be more cryptic. For example, if we change this line inside the checkGuess() function:

var userGuess = Number(guessField.value);

to

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

It throws this error because it thinks you are trying to do something different. You should make sure that you don't mix up the assignment operator (=) — which sets a variable to be equal to a value — with the strict equality operator (===), which tests whether one value is equal to another, and returns a true/false result.

Note: See our SyntaxError: missing ; before statement reference page for more details about this error.

The program always says you've won, regardless of the guess you enter

This could be another symptom of mixing up the assignment and strict equality operators. For example, if we were to change this line inside checkGuess():

if (userGuess === randomNumber) {

to

if (userGuess = randomNumber) {

the test would always return true, causing the program to report that the game has been won. Be careful!

SyntaxError: missing ) after argument list

This one is pretty simple — it generally means that you've missed the closing parenthesis off the end of a function/method call.

Note: See our SyntaxError: missing ) after argument list reference page for more details about this error.

SyntaxError: missing : after property id

This error usually relates to an incorrectly formed JavaScript object, but in this case we managed to get it by changing

function checkGuess() {

to

function checkGuess( {

This has caused the browser to think that we are trying to pass the contents of the function into the function as an argument. Be careful with those parentheses!

SyntaxError: missing } after function body

This is easy — it generally means that you've missed one of your curly braces from a function or conditional structure. We got this error by deleting one of the closing curly braces near the bottom of the checkGuess() function.

SyntaxError: expected expression, got 'string' or SyntaxError: unterminated string literal

These errors generally mean that you've missed off a string value's opening or closing quote mark. In the first error above, string would be replaced with the unexpected character(s) that the browser found instead of a quote mark at the start of a string. The second error means that the string has not been ended with a quote mark.

For all of these errors, think about how we tackled the examples we looked at in the walkthrough. When an error arises, look at the line number you are given, go to that line and see if you can spot what's wrong. Bear in mind that the error is not necessarily going to be on that line, and also that the error might not be caused by the exact same problem we cited above!

Note: See our SyntaxError: Unexpected token and SyntaxError: unterminated string literal reference pages for more details about these errors.

Summary

So there we have it, the basics of figuring out errors in simple JavaScript programs. It won't always be that simple to work out what's wrong in your code, but at least this will save you a few hours of sleep and allow you to progress a bit faster when things don't turn out right earlier on in your learning journey.

See also

  • There are many other types of error that aren't listed here; we are compiling a reference that explains what they mean in detail — see the JavaScript error reference.
  • If you come across any errors in your code that you aren't sure how to fix after reading this article, you can get help! Ask on the Learning Area Discourse thread, or in the #mdn IRC channel on Mozilla IRC. Tell us what your error is, and we'll try to help you. A listing of your code would be useful as well.

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

 Внесли вклад в эту страницу: nikitapoly
 Обновлялась последний раз: nikitapoly,