JavaScript - 扩展错误

你好,未来的JavaScript大师们!今天,我们将深入探索JavaScript中扩展错误的精彩世界。如果你是编程新手,不用担心——我将作为你的友好向导,带领你进行这次冒险。在本课结束时,你将能够像一个专业人士一样创建你自己的自定义错误!

JavaScript - Extending Errors

扩展Error类:创建自定义错误

让我们从基础开始。在JavaScript中,我们有一个内置的Error类,我们可以用它来创建错误对象。但有时,我们的应用程序需要更具体的错误。这就是扩展Error类派上用场的地方!

为什么扩展错误?

想象一下,你正在构建一个烹饪应用程序,你想要为厨房事故创建特定的错误。你可以使用通用的Error,但拥有一个BurnedFoodError(烧焦食物错误)或OverseasonedError(过度调味错误)不是更好吗?这就是我们要学习的内容!

扩展错误的基本语法

让我们从一个简单的例子开始:

class KitchenError extends Error {
constructor(message) {
super(message);
this.name = 'KitchenError';
}
}

让我们分解一下:

  1. 我们使用class关键字定义我们的新错误类。
  2. extends Error告诉JavaScript,我们的新类应该继承自内置的Error类。
  3. constructor中,我们调用super(message)以确保父类Error被正确初始化。
  4. 我们设置this.name来给我们的错误一个特定的名称。

现在,让我们看看如何使用这个:

try {
throw new KitchenError("意大利面粘在天花板上了!");
} catch (error) {
console.log(error.name); // 输出:KitchenError
console.log(error.message); // 输出:意大利面粘在天花板上了!
}

添加自定义属性

扩展错误最酷的事情之一是我们可以添加自己的自定义属性。让我们增强我们的KitchenError

class KitchenError extends Error {
constructor(message, dish) {
super(message);
this.name = 'KitchenError';
this.dish = dish;
}
}

try {
throw new KitchenError("烧焦了!", "烤宽面条");
} catch (error) {
console.log(`哦不!${error.dish}出问题了:${error.message}`);
// 输出:哦不!烤宽面条出问题了:烧焦了!
}

在这个例子中,我们给我们的错误添加了一个dish属性。这允许我们提供更多关于厨房灾难中究竟出了什么问题的上下文!

创建特定的错误类型

既然我们知道如何扩展Error类,让我们为我们的厨房应用程序创建一些特定的错误类型:

class BurnedFoodError extends KitchenError {
constructor(dish) {
super(`The ${dish} is burned to a crisp!`, dish);
this.name = 'BurnedFoodError';
}
}

class OverseasonedError extends KitchenError {
constructor(dish, seasoning) {
super(`The ${dish} is over-seasoned with ${seasoning}!`, dish);
this.name = 'OverseasonedError';
this.seasoning = seasoning;
}
}

现在我们可以在我们的代码中使用这些特定的错误类型:

function cookDinner(dish, seasoning) {
if (Math.random() < 0.5) {
throw new BurnedFoodError(dish);
} else if (Math.random() < 0.5) {
throw new OverseasonedError(dish, seasoning);
}
console.log(`你的${dish}烹饪得恰到好处!`);
}

try {
cookDinner("牛排", "盐");
} catch (error) {
if (error instanceof BurnedFoodError) {
console.log(`哎呀!${error.message}该点外卖了。`);
} else if (error instanceof OverseasonedError) {
console.log(`哎哟!${error.message}下次也许少用点${error.seasoning}。`);
} else {
console.log("厨房里出了点问题!");
}
}

这段代码模拟了烹饪的不确定性(至少对我们中的一些人来说是这样!)并展示了我们如何以不同的方式处理不同类型的错误。

多级继承

现在,让我们将我们的错误层次结构提升到一个新的层次——字面上!我们可以创建一个错误类型的链,每个类型都继承自前一个类型。这称为多级继承。

让我们扩展我们的厨房错误系统:

class KitchenApplianceError extends KitchenError {
constructor(message, appliance) {
super(message);
this.name = 'KitchenApplianceError';
this.appliance = appliance;
}
}

class OvenError extends KitchenApplianceError {
constructor(message) {
super(message, 'oven');
this.name = 'OvenError';
}
}

class MicrowaveError extends KitchenApplianceError {
constructor(message) {
super(message, 'microwave');
this.name = 'MicrowaveError';
}
}

在这个例子中:

  • KitchenApplianceError继承自KitchenError
  • OvenErrorMicrowaveError都继承自KitchenApplianceError

让我们看看如何使用这个层次结构:

function useAppliance(appliance) {
if (appliance === 'oven') {
throw new OvenError("烤箱加热不了!");
} else if (appliance === 'microwave') {
throw new MicrowaveError("微波炉发出奇怪的声音!");
}
}

try {
useAppliance('oven');
} catch (error) {
if (error instanceof OvenError) {
console.log(`烤箱问题:${error.message}`);
} else if (error instanceof MicrowaveError) {
console.log(`微波炉问题:${error.message}`);
} else if (error instanceof KitchenApplianceError) {
console.log(`通用设备错误,涉及${error.appliance}:${error.message}`);
} else if (error instanceof KitchenError) {
console.log(`厨房错误:${error.message}`);
} else {
console.log(`意外错误:${error.message}`);
}
}

这种多级继承允许我们创建非常具体的错误类型,同时仍然保持逻辑上的层次结构。我们可以在不同级别的具体性捕获错误,从最具体的(OvenError)到最一般的(Error)。

方法表

以下是我们自定义错误中使用的关键方法和属性的总结:

方法/属性 描述 示例
constructor() 初始化错误对象 constructor(message, dish)
super() 调用父类构造器 super(message)
this.name 设置错误的名称 this.name = 'KitchenError'
this.[custom] 添加自定义属性 this.dish = dish
instanceof 检查对象是否是类的实例 if (error instanceof OvenError)

记住,扩展错误不仅仅是给你的错误起个花哨的名字——它是关于在代码中以结构化的方式处理不同类型的错误。这可以使调试更容易,并使你的错误信息更加详细和具体。

所以,下次你编程时出了问题,不要只抛出一个通用错误——创建一个自定义的错误!谁知道呢,也许你的CodeSpaghettiError(代码意大利面错误)会成为你开发团队的热门话题。快乐编程,愿你的所有错误都能完美扩展!

Credits: Image by storyset