MDN will be in maintenance mode on Wednesday September 20th, starting at 10 AM Pacific / 5 PM UTC, for about 1 hour.

当你在上一篇文章中建立了“猜数字”游戏,你可能会发现它没有工作。不要害怕 - 这篇文章旨在通过提供一些简单的提示,如何找到和修复JavaScript程序中的错误,帮助你免受这些让人挠头的问题的困扰。

先决条件: 基本的计算机素养,基本了解HTML和CSS,了解JavaScript是什么。
目的: 获得能力和信心开始修复自己的代码中的简单问题。

错误类型

     一般来说,当你在代码中做错了,你会遇到两种主要的错误类型:

  • 语法错误:这是在你的代码的拼写错误,实际上导致程序不能运行在所有或停止通过工作的一部分,这样你通常会用一些错误消息也提供了通常可以修复的方法,只要你熟悉正确的工具,知道错误消息的意思!
  • 逻辑错误:这些错误,其中语法实际上是正确的,但代码是不是你想要的,这意味着项目成功运行,但会产生不正确的结果。这些通常比语法错误更难以修复,因为通常没有错误指向错误源。

好了,这是不是很简单-因为你更深入的研究也有一些其他的差异化。但上述分类将在你的职业生涯的这个早期阶段做。我们将看看这两种类型。

一个错误的例子

开始,让我们回到猜测游戏 - 除了这一次,我们将探索一个版本,有一些故意错误介绍。转到Github上,将 数游戏errors.html 拷贝到本地(看到它在这里住上运行)。

  1. 要开始,请在您喜欢的文本编辑器和浏览器中打开本地副本。
  2. 尝试玩游戏 - 你会注意到,当你按“提交猜测”按钮,它不工作!

注意:您的游戏也可能不工作,您可能要修正!我们仍然希望您能够使用我们的版本来完成这篇文章,以便您可以学习我们在这里教授的技术。然后你可以回去,尝试修复你的例子。

此时,让我们打开开发者控制台,看看我们是否可以有语法错误,然后尝试修复它们。你会学到如何修复。

修复语法错误

早年在过程中,我们得到了你输入一些简单的JavaScript命令到开发工具JavaScript控制台(如果你不记得如何在浏览器中打开此,按照前面的链接了解如何 F12.)。更有用的是,当JavaScript进入浏览器的JavaScript引擎时,如果存在语法错误,控制台会提供错误消息。现在让我们去看一看。

  1. 在谷歌浏览器打开errors.html中打开,并打开JavaScript控制台(默认F12)。您应该会看到以下行中的错误消息:
  2. 这是一个很容易跟踪的错误,浏览器提供了几个有用的信息来帮助你(上面的截图是从Firefox,但其他浏览器提供类似的信息)。从左到右,我们有:
  • 红色 “x” 表示这是一个错误。
  • 一个错误消息,指示发生了什么问题:“TypeError:guessSubmit.addeventListener不是一个函数”
  • 点击错误链接浏览器解释了大量详细信息含义
  • 错误所在的行号,以及首次看到错误的行中的字符编号。在这种情况下,我们有第86行,字符数3。
  1. 如果我们在代码编辑器中看第86行,我们会发现这行:
  2. guessSubmit.addeventListener('click', checkGuess);
  3. 错误消息说“guessSubmit.addeventListener不是一个函数”,所以我们可能拼写错了。如果你不确定一段语法的正确拼写,在MDN上查找该功能通常是很好的。当前做到这一点,最好的办法就是搜索“MDN 名称的特征在你喜欢的搜索引擎。” 这里有快捷链接,为您节省在这种情况下:addEventListener()
  4. 所以,看着这个页面,错误似乎是我们拼写的函数名错误!请记住,JavaScript是区分大小写的,所以任何轻微的拼写或大小不同都会导致错误。更改addeventListeneraddEventListener解决这个问题。现在。

:请参阅我们的类型错误:“x”是不是一个函数有关此错误的详细情况参考页。

语法错误二

  1. 保存您的页面并刷新,您会看到错误已经消失。
  2. 现在,如果你尝试输入一个猜测,并按提交猜测按钮,你会看到...另一个错误!
  3. 这次报告的错误是“TypeError:lowOrHi is null”,在第78行。
    注意Null是一个特殊值,意思是“无”,或者“无值”。因此,lowOrHi已申报和初始化,但不与任何有意义的价值-它没有任何类型或值。
    注意 因为(内部函数内部发生这个错误checkGuess() { ... }块)。正如你将在后面的函数文章中更详细地学到的,代码里面的函数运行在一个单独的范围内来编写外部函数。在这种情况下,代码没有运行并且没有被抛出的误差,直到checkGuess()函数由线86上运行。
  4. 看看第78行,你会看到下面的代码:
    lowOrHi.textContent = 'Last guess was too high!';
  5. 该行正试图设置textContent的中lowOrHi变量为一个文本字符串,但它不工作,因为lowOrHi不包含什么它应该操作不了。让我们来看看这是为什么-尝试搜索的其他实例lowOrHi中的代码。你在JavaScript中找到的最早的例子是第48行:
    var lowOrHi = document.querySelector('lowOrHi');
  6. 在这一点上,我们试图让变量包含对文档HTML中的元素的引用。让我们来检查值是否是null运行后。在第49行添加以下代码:
    console.log(lowOrHi);

    注意console.log()是一个非常有用的调试功能,打印的值到控制台。所以它会打印的价值lowOrHi,快速的打印到控制台,我们曾试图将其设置为48行。

  7. 保存并刷新,你现在应该看到console.log()的结果在控制台。 果然,lowOrHi的值是null在这一点上,所以绝对没有48中的问题。
  8. 让我们想想问题可能是什么。48号线使用document.querySelector()方法与CSS选择器选择它去一个元素的引用。进一步查看我们的文件,我们可以找到有问题的段落:
    <p class="lowOrHi"></p>
  9. 因此,我们需要一个类在这里,它与一个点开始(.),但选择器被传递到querySelector()方法中管线48没有圆点。这可能是问题!尝试改变lowOrHi,以.lowOrHi行号48。
  10. 尝试保存并刷新一遍,你的console.log()说法应该返回<p>我们想要的元素。!!另一个错误修复!您可以删除您console.log(),或保持在随后参考-你的选择。

:请参阅我们的类型错误:“x”是(不)“Y”参考有关此错误的更多详细信息页面。

第三个语法错误

  1. 现在,如果你再次尝试玩游戏,你应该获得更多的成功 - 游戏应该通过,直到你结束游戏,通过猜测正确的数字,或通过运行重置。
  2. 在这一点,游戏再次失败,同样的错误是抛出,我们在开始 - “TypeError:resetButton.addeventListener不是一个函数!这次它来自第94行。
  3. 看看行号94,很容易看到我们在这里犯了同样的错误。我们再次只需要改变addeventListeneraddEventListener现在做这个。

一个逻辑错误

在这一点上,游戏进行得很顺利。但经过几次你一定会注意到你要猜测的这个随机数总是1。毋庸置疑,我们不想这么玩游戏!

可以确定的是,某处游戏的逻辑出现了问题——游戏并没有返回错误;它只是不能正确地运行。

  1. 找到我们第一次声明变量randomNumber所在的位置。这个我们要在游戏开始时猜测的随机数实例大约出现在44行:
    var randomNumber = Math.floor(Math.random()) + 1;
    另一个在随后的每一次游戏前形成的随机数实例应该在113行:
    randomNumber = Math.floor(Math.random()) + 1;
  2. 为了检查是否这两行确实存在问题,让我们再次回到我们的朋友控制台——在上面两行代码之后各自插入下面的代码:
    console.log(randomNumber);
  3. 保存并刷新,然后进行游戏——你会看到在它被输入到控制台的地方随机数总是等于1。

通过逻辑工作

确定了这个,让我们来思考这行代码如何工作。首先,我们调用 Math.random(),它生成一个在0和1之间的十进制随机数,例如 0.5675493843。

Math.random()

接下来,我们把调用Math.random()的结果作为参数传递给Math.floor(),它会向下舍入到与它最接近的整数。然后我们给这个结果加上1

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

舍入介于 0 和 1 下的之间的十进制随机数将总是返回 0,所以加1之后它总是返回1。我们需要在它舍入之前将它乘以100。那么接下来的结果就是0到99之间的随机数了:

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

因此我们考虑加1,才会给我们一个1到100之间的随机整数:

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

试着像这样更新这两行,然后保存并刷新——现在游戏应该是我们期望的那样了!

其它常见错误

在代码中会遇到其他常见错误。 本节指出其中的大部分。

语法错误: 在声明后缺少" ; "

这个错误通常意味着你漏掉了代码行后面的分号,但是它有时候会变得更神秘。例如如果我们把 checkkGuess() 函数中的这一行 :

var userGuess = Number(guessField.value);

改成

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

它会抛出一个错误因为它认为你在做不同的事。你应该确定你没有把设置变量等于一个值的赋值运算符(=)和测试两个变量是否相等并返回 true/false 的严格相等运算符(===)弄混淆。

: 通过我们的 SyntaxError: missing ; before statement 参考页面来获得有关此错误的更多详细信息。

不管你输入的猜测是什么程序都说“你赢了!”

这可能是混淆赋值和严格相等运算符的又一症状。例如我们把 checkGuess() 里面的:

if (userGuess === randomNumber) {

改成

if (userGuess = randomNumber) {

因为条件永远返回 true,所以程序报告说游戏已经赢了,小心哦!

语法错误: 在参数后缺少" ) "

这个很简单 — 它通常意味着你丢失了函数、方法调用后面的结束括号。

: 通过我们的 SyntaxError: missing ) after argument list 参考页面来获得有关此错误的更多详细信息。

语法错误: 在属性id后缺少" : "

这个错误通常涉及到错误形成的JavaScript对象,我们要得到这个错误,把

function checkGuess() {

改成

function checkGuess( {

这导致浏览器认为我们试图将函数的内容传递给函数作为参数。小心那些圆括号!

语法错误: 在函数体后缺少" } "

这个简单 —它通常意味着你的函数或条件结构中丢失了一个花括号。我们通过删除 checkGuess() 函数底部附近的花括号来得到这个错误。

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

这个错误通常意味着你丢失了字符串值的开引号或关引号。 在上面的第一个错误中,string 将被替换为浏览器发现的意外字符,而不是字符串开头的引号。第二个错误意味着字符串没有用引号结尾。

对于所有的这些错误,想想我们是如何解决在演示中看到的这些例子。当一个错误出现,看你得到的错误所在行的行号,去到那一行看看你能发现是什么错。记住,错误不一定会在那一行,而且错误可能不是由我们上面提到的相同的问题所造成的!

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

总结

我们有了能够在简单的JavaScript程序中解决错误的基础知识。解决代码中的错误并不是总会那么简单,但至少可以节省出你几个小时的睡觉觉时间,让你的学习过程中不出现问题而进展的更快速。

也可以看看这些

  • 许多错误不能一一的在这里列出来;我们正在编写一个参考文档来详细的说明他们的含义 — see the JavaScript error reference.
  • 如果你在阅读了这篇文章之后在你的代码中遇到了一些错误而你不知道如何解决,你能够得到别人的帮助! 问学习区话题线,告诉我们你遇到的错误是什么,我们会尽量帮助你。附加一段你的代码也是很有用的。

文档标签和贡献者

 此页面的贡献者: jswisher, leezw, Bigbigbig, dudusky, Zhsirting, billdeng, quanjingkuan
 最后编辑者: jswisher,