什么地方出了错?
先决条件: | 基本的计算机素养,基本了解HTML和CSS,了解JavaScript是什么。 |
---|---|
目的: | 获得能力和信心开始修复自己的代码中的简单问题。 |
错误类型
一般来说,当你在代码中做错了,你会遇到两种主要的错误类型:
- 语法错误:这是在你的代码的拼写错误,实际上导致程序不能运行在所有或停止通过工作的一部分,这样你通常会用一些错误消息也提供了通常可以修复的方法,只要你熟悉正确的工具,知道错误消息的意思!
- 逻辑错误:这些错误,其中语法实际上是正确的,但代码是不是你想要的,这意味着项目成功运行,但会产生不正确的结果。这些通常比语法错误更难以修复,因为通常没有错误指向错误源。
好了,这是不是很是简单-因为你更深入的研究也有一些其他的差异化。但上述分类将在你的职业生涯的这个早期阶段做。我们将看看这两种类型。
一个错误的例子
开始,让我们回到我们的猜测游戏 - 除了这一次,我们将探索一个版本,有一些故意错误介绍。转到Github上,让自己的本地拷贝数游戏errors.html(看到它在这里住上运行)。
- 要开始,请在您喜欢的文本编辑器和浏览器中打开本地副本。
- 尝试玩游戏 - 你会注意到,当你按"提交猜测"按钮,它不工作!
注意:您可能也有自己的游戏不工作,您可能要修正!我们仍然希望您能够使用我们的版本来完成这篇文章,以便您可以学习我们在这里教授的技术。然后你可以回去,尝试修复你的例子。
此时,让我们打开开发者控制台,看看我们是否可以有语法错误,然后尝试修复它们。你会学到如何修复。
修复语法错误
早年在过程中,我们得到了你输入一些简单的JavaScript命令到开发工具JavaScript控制台(如果你不记得如何在浏览器中打开此,按照前面的链接了解如何 F12.)。更有用的是,当JavaScript进入浏览器的JavaScript引擎时,如果存在语法错误,控制台会提供错误消息。现在让我们去看一看。
-
在谷歌浏览器打开errors.html
中打开,并打开JavaScript控制台(默认F12)。您应该会看到以下行中的错误消息: - 这是一个很容易跟踪的错误,浏览器提供了几个有用的信息来帮助你(上面的截图是从Firefox,但其他浏览器提供类似的信息)。从左到右,我们有:
- 红色"x"表示这是一个错误。
- 一个错误消息,指示发生了什么问题:"TypeError:guessSubmit.addeventListener不是一个函数"
- 点击错误链接浏览器解释了大量详细信息含义
- 错误所在的行号,以及首次看到错误的行中的字符编号。在这种情况下,我们有第86行,字符数3。
- 如果我们在代码编辑器中看第86行,我们会发现这行:
guessSubmit.addeventListener('click', checkGuess);
- 错误消息说"guessSubmit.addeventListener不是一个函数",所以我们可能拼写错了。如果你不确定一段语法的正确拼写,在MDN上查找该功能通常是很好的。当前做到这一点,最好的办法就是搜索"MDN 名称的特征在你喜欢的搜索引擎。" 这里有快捷链接,为您节省在这种情况下:
addEventListener()
。 - 所以,看着这个页面,错误似乎是我们拼写的函数名错误!请记住,JavaScript是区分大小写的,所以任何轻微的拼写或大小不同都会导致错误。更改
addeventListener
到addEventListener
解决这个问题。现在。
注:请参阅我们的类型错误:"x"是不是一个函数有关此错误的详细情况参考页。
语法错误二
- 保存您的页面并刷新,您会看到错误已经消失。
- 现在,如果你尝试输入一个猜测,并按提交猜测按钮,你会看到...另一个错误!
- 这次报告的错误是"TypeError:lowOrHi is null",在第78行。 注意:
Null
是一个特殊值,意思是"无",或者"无值"。因此,lowOrHi
已申报和初始化,但不与任何有意义的价值-它没有任何类型或值。注意 因为(内部函数内部发生这个错误checkGuess() { ... }
块)。正如你将在后面的函数文章中更详细地学到的,代码里面的函数运行在一个单独的范围内来编写外部函数。在这种情况下,代码没有运行并且没有被抛出的误差,直到checkGuess()
函数由线86上运行。 - 看看第78行,你会看到下面的代码:
lowOrHi.textContent = 'Last guess was too high!';
- 该行正试图设置
textContent
的中lowOrHi
变量为一个文本字符串,但它不工作,因为lowOrHi
不包含什么它应该操作不了。让我们来看看这是为什么-尝试搜索的其他实例lowOrHi
中的代码。你在JavaScript中找到的最早的例子是第48行:var lowOrHi = document.querySelector('lowOrHi');
- 在这一点上,我们试图让变量包含对文档HTML中的元素的引用。让我们来检查值是否是
null
运行后。在第49行添加以下代码:console.log(lowOrHi);
注意:
console.log()
是一个非常有用的调试功能,打印的值到控制台。所以它会打印的价值lowOrHi
,快速的打印到控制台,我们曾试图将其设置为48行。 - 保存并刷新,你现在应该看到
console.log()
的结果在控制台。 果然,lowOrHi
的值是null
在这一点上,所以绝对没有48中的问题。 - 让我们想想问题可能是什么。48号线使用
document.querySelector()
方法与CSS选择器选择它去一个元素的引用。进一步查看我们的文件,我们可以找到有问题的段落:<p class="lowOrHi"></p>
- 因此,我们需要一个类在这里,它与一个点开始(.),但选择器被传递到
querySelector()
方法中管线48没有圆点。这可能是问题!尝试改变lowOrHi
,以.lowOrHi
行号48。 - 尝试保存并刷新一遍,你的
console.log()
说法应该返回<p>
我们想要的元素。!!另一个错误修复!您可以删除您console.log()
,或保持在随后参考-你的选择。
注:请参阅我们的类型错误:"x"是(不)"Y"参考有关此错误的更多详细信息页面。
第三个语法错误
- 现在,如果你再次尝试玩游戏,你应该获得更多的成功 - 游戏应该通过,直到你结束游戏,通过猜测正确的数字,或通过运行重置。
- 在这一点,游戏再次失败,同样的错误是抛出,我们在开始 - "TypeError:resetButton.addeventListener不是一个函数!这次它来自第94行。
- 看看行号94,很容易看到我们在这里犯了同样的错误。我们再次只需要改变
addeventListener
为addEventListener
。现在做这个。
逻辑错误
在这一点上,游戏进行得很顺利。但经过几次你一定会注意到你要猜测的这个随机数总是1。毋庸置疑,我们不想这么玩游戏!
可以确定的是,某处游戏的逻辑出现了问题——游戏并没有返回错误;它只是不能正确地运行。
- 找到我们第一次声明变量randomNumber所在的位置。这个我们要在游戏开始时猜测的随机数实例大约出现在44行:
var randomNumber = Math.floor(Math.random()) + 1;
另一个在随后的每一次游戏前形成的随机数实例应该在113行:randomNumber = Math.floor(Math.random()) + 1;
- 为了检查是否这两行确实存在问题,让我们再次回到我们的朋友控制台——在上面两行代码之后各自插入下面的代码:
console.log(randomNumber);
- 保存并刷新,然后进行游戏——你会看到在它被输入到控制台的地方随机数总是等于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;
试着像这样更新这两行,然后保存并刷新——现在游戏应该是我们期望的那样了!
其它常见错误
还有其他常见错误,你会在代码中遇到。 本节重点介绍其中的大部分。
语法错误: 在声明后缺少" ; "
这个错误通常意味着你在一行代码的末尾错过了一个冒号,但有时它会更加隐秘。 例如,如果我们在 checkGuess()
函数中更改此行:
var userGuess = Number(guessField.value);
至
var userGuess === Number(guessField.value);
它抛出这个错误,因为它认为你正在尝试做不同的事情。 你应该确保不要使用strict等于运算符混合赋值运算符( =
) - 它设置一个变量等于一个值( === code>),它测试一个值是否等于另一个值,并返回
true
/ false
结果。
请注意:请参阅我们的语法错误:missing; before语句参考页,以获取有关此错误的更多详细信息。
程序总是说你赢了,无论你进入猜测
这可能是混淆赋值和严格相等运算符的另一个症状。 例如,如果我们在 checkGuess()
中更改此行:
if (userGuess === randomNumber) {
至
if (userGuess = randomNumber) {
测试总是返回true,所以程序报告游戏已经赢了。 小心!
语法错误: 在参数后缺少" ) "
这很简单 - 通常意味着你错过了一个函数/方法调用结束时的右括号。
注意:请参阅参数列表后的 SyntaxError:missing) 参考页,了解有关此错误的更多详细信息。
语法错误: 在属性id后缺少" : "
这个错误通常与一个不正确形成的JavaScript对象有关,但在这种情况下,我们设法通过更改获得它
function checkGuess() {
至
function checkGuess( {
这导致浏览器认为我们试图将函数的内容作为参数传递到函数中。 小心这些括号!
语法错误: 在函数体后缺少" } "
这很容易 - 通常意味着你从一个函数或条件结构中错过了一个花括号。 我们通过删除 checkGuess()
函数底部附近的一个关闭花括号来获得此错误。
SyntaxError:expected expression,got\' string \'或SyntaxError:unterminated string literal
这些错误通常意味着您错过了字符串值的开头或结尾引号。 在上面的第一个错误中, string 将替换为浏览器找到的意外字符,而不是字符串开头的引号。 第二个错误表示字符串尚未以引号标记结束。
对于所有这些错误,想想我们如何处理我们在演练中看到的例子。 当出现错误时,查看您给出的行号,转到该行,看看是否可以发现错误。 记住,错误不一定是在那行,也错误可能不是由上面提到的完全相同的问题引起的!
注意:请参阅我们的语法错误:意外令牌 >和 SyntaxError:unterminated string literal 参考页面了解有关这些的更多详细信息 错误。
概要
所以我们有它,在简单的JavaScript程序中找出错误的基础。 它不总是那么简单,弄清楚你的代码有什么问题,但至少这将节省你几个小时的睡眠,并允许你进步一点,当事情没有出现在你的学习之前 。
也可以看看
- 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! E-mail us on the dev-mdc mailing list and tell us what your error is, and we'll try to help you. A listing of your code would be useful as well.