JavaScript常见错误:ReferenceError、SyntaxError和TypeError的诊断与解决

引言

JavaScript 是一种用于前端和后端开发的编程语言。在使用 JavaScript 时,解读错误消息可能会感觉有点令人望而生畏。当您在应用程序中解决问题时,理解错误消息所指的内容非常重要。幸运的是,现代浏览器都附带了内置的调试工具来帮助解决这个问题。每个浏览器在可视化表示方面处理错误消息的方式都不同。然而,错误消息能够让您了解到您的 JavaScript 代码发生了什么。

在本教程中,您将学习关于浏览器环境下出现的三种常见的 JavaScript 错误类型:ReferenceError(引用错误)、SyntaxError(语法错误)和 TypeError(类型错误)。为了跟上,请确保您对 JavaScript 和开发者控制台有一定的理解。

您可以通过我们的 JavaScript 编码教程 了解更多关于 JavaScript 的知识,通过我们的 JavaScript 开发者控制台教程 了解关于开发者控制台的使用方法。

以下示例并非详尽无遗,只是对您可能遇到的常见错误消息进行初步介绍。此外,示例中的错误消息来自 Chrome 网页浏览器。您在 Firefox 或 Edge 上收到的错误消息可能略有不同,但错误类型是相同的。

理解 JavaScript 错误类型

JavaScript 中的错误基于 Error 对象。它是一个内置对象,包含关于发生的错误类型的信息,然后是详细说明可能原因的消息。例如,您可能遇到一个类似以下的错误:

VM170:1 Uncaught ReferenceError: shark is not defined
    at <anonymous>:1:1

如果您对这个错误信息进行解构,您会发现 ReferenceError 是被识别出来的错误类型。分号后的错误信息描述了错误:shark 未定义。此信息的最后一行详细说明了错误在您的代码 1:1 处发生。

每当浏览器捕获到错误时,错误的类型和消息会指示问题所在。通过这些信息,您可以根据接收到的错误类型和消息来确定如何调试代码。

理解 ReferenceError

当您尝试访问尚未创建的变量时,会发生一个“引用错误”。它还会在初始化变量之前调用变量时发生。

遇到未定义的变量

例如,如果您在执行 console.log() 时拼写变量名称错误,您将收到一个 ReferenceError

let sammy = 'A Shark dreaming of the cloud.';

console.log(sammmy);
输出
Uncaught ReferenceError: sammmy is not defined at <anonymous>:1:13

变量 sammmy,有三个 m,不存在且未定义。要解决这个错误,您可以把变量更新为正确的拼写,并再次运行命令。如果成功,就不会收到错误消息。总体而言,检查代码中的任何拼写错误可以帮助避免未定义变量的错误。

在变量被声明之前访问

同样,当您尝试在代码中访问一个变量在其声明之前时,可能会遇到以下错误。

function sharkName() {
    console.log(shark);

    let shark = 'sammy';
}
输出
VM223:2 Uncaught ReferenceError: Cannot access 'shark' before initialization at sharkName (<anonymous>:2:17) at <anonymous>:1:1

在这个例子中,console.log(shark)shark 变量声明之前被执行,这导致了错误的发生。一般来说,在尝试访问变量之前先声明变量是一个很好的做法。

注意:由于 letconst 声明的处理方式,这些声明在上一个示例中被提升,但目前无法访问。在这种情况下,letconst 变量进入所谓的“暂时死区”。为了避免这种情况,请在作用域的开始声明您的 letconst 变量。为了修复示例代码,请在执行 console.log() 命令之前声明 shark 变量。

function sharkName() {
    let shark = 'sammy';

    console.log(shark);
}

ReferenceError 经常与您的变量和作用域相关联。虽然这超出了本教程的范围,但您可以在我们的《理解 JavaScript 中的变量、作用域和提升》教程中了解更多关于作用域、不同变量类型和变量提升的知识。

理解 SyntaxError

当 JavaScript 解释器遍历您的代码时,如果遇到不符合语言规范的代码,它可能会抛出 SyntaxError。如果发生这种情况,您的代码将停止执行,并收到有关语法错误的消息。

缺失的代码封装

例如,当你编写一个函数时,如果忘记用右括号 “)” 包裹代码,你将收到一条特定的 SyntaxError 消息,提示你缺少了什么。

function sammy(animal) {
    if(animal == 'shark'){
        return `I'm cool`;
    } else {
        return `You're cool`;
    }
}

sammy('shark';
输出
Uncaught SyntaxError: missing ) after argument list

幸运的是,错误信息指明了代码中缺失的元素。在这个例子中,sammy 函数调用缺少了闭合的 ) 括号。

. . .

sammy('shark');

如果在函数的末尾省略了结束花括号 },或者在数组中省略了右方括号 ],也会抛出这个错误。请确保正确地关闭你的函数、数组和对象。

声明相同的变量名称

当函数参数和函数体内部使用相同的变量名时,您也可能会遇到这个错误。请看下面的例子:

function sammy(animal) {
    let animal = 'shark';
}
输出
VM132:2 Uncaught SyntaxError: Identifier 'animal' has already been declared

为了修复错误,请确保在函数体内创建唯一且具体的变量名。例如,通过声明一个新的变量名,比如 animalType,你可以消除函数参数和函数体内 let 变量之间的冲突。

function sammy(animal) {
    let animalType = 'shark';
}

如果你打算在函数体内更改或使用参数,请不要使用具有相同变量名的变量声明。例如,你可以在函数体内删除 let 声明。

function sammy(animal) {
    animal = 'shark';
}

确保在函数体内外使用变量时,给它们起独特的名称。在访问函数参数时,可以在函数体内直接使用它,而无需像 let 一样进行变量声明。

识别意外标记

这是文章《如何在JavaScript中解决’ReferenceError’,’SyntaxError’和’TypeError’问题》的第3部分(共5部分)。

内容片段: 就像忘记了一个括号 `]` 或者一个花括号 `}` 一样,有时你可能需要对你的代码进行一个微小但关键的添加。例如:

let sharkCount = 0;

function sammy() {
    sharkCount+;
    console.log(sharkCount);
}
输出
Uncaught SyntaxError: Unexpected token ';'

在这个例子中,多余的元素是函数体内的 `sharkCount` 后面的加号。正确的自增操作符应该是 `++`。

. . .
function sammy() {
    sharkCount++;
    console.log(sharkCount);
}

当遇到“`SyntaxError: Unexpected token`”时,请仔细检查你的代码是否缺少或多余了像加号(`+`)这样的操作符。

理解 TypeError(类型错误)

当函数或变量的值是意外类型时,会发生类型错误(`TypeError`)。您可以通过查阅我们的《了解JavaScript数据类型》教程,更多了解不同的JavaScript数据类型。

在对象上使用数组方法

一个常见的错误是使用数组方法来遍历对象。例如,您不能使用 `.map()` 方法来循环遍历对象,因为该方法只适用于数组。

const sharks = {
    shark1: 'sammy',
    shark2: 'shelly',
    shark3: 'sheldon'
}

sharks.map((shark) => `Hello there ${shark}!`);
输出

这是文章《如何在JavaScript中解决’ReferenceError’,’SyntaxError’和’TypeError’问题》的第4部分(共5部分)。

Uncaught TypeError: sharks.map is not a function at <anonymous>:1:8

修复上一个例子的一种方法是使用for...in循环,在sharks对象上工作,以获取值:

const sharks = {
    shark1: 'sammy',
    shark2: 'shelly',
    shark3: 'sheldon'
}

for (let key in sharks) {
    console.log(`大家好,我是 ${sharks[key]}`);
}

或者,你可以将sharks对象转换为数组,以便使用.map()方法:

const sharks = ['sammy', 'shelly', 'sheldon'];

sharks.map((shark) => `大家好,我是 ${shark}`);

当你处理不同的数组和对象时,很容易混淆各种方法。请仔细核查你使用的方法是否适用于所处理的数据类型。

使用正确的解构方法

同样,尝试使用数组解构来遍历一个对象将抛出一个TypeError错误。

const shark = {
    name: 'sammy',
    age: 12,
    cloudPlatform: 'Silicon Cloud'
}

const [name, age, cloudPlatform] = sharks;
输出

这是文章《如何在JavaScript中解决’ReferenceError’,’SyntaxError’和’TypeError’问题》的第5部分(共5部分)。

VM23:7 Uncaught TypeError: sharks is not iterable at <anonymous>:7:26

解决这个问题的一种方法是使用对象解构来基于对象的键创建新变量。

const shark = {
    name: 'sammy',
    age: 12,
    cloudPlatform: 'Silicon Cloud'
}

const {name, age, cloudPlatform} = shark;

console.log(name);
输出
sammy

根据您的数据结构是使用数组还是对象,请确保使用适当的方法来获取值。

结论

在本教程中,您学习了关于三种常见的JavaScript错误类型,以及它们相关的消息和如何在遇到常见问题时进行调试的内容。虽然本文并非包罗万象,但您已经获得了关于JavaScript和浏览器如何共同指示代码中问题的见解。

您可以了解更多关于如何使用JavaScript对象方法JavaScript数组方法,以更好地理解如何应用这些方法。

您还可以通过我们的“如何使用Google Chrome开发工具和Visual Studio Code调试JavaScript”教程,了解更多关于使用Chrome开发工具进行调试的方法。

bannerAds