当程序或某段代码出错,或出现意外情况时,把错误报告出来是很有用的。
错误是 JavaScript 对象。
这个对象的主要属性是message:
const error = new Error('Oops, something went wrong');
console.log(error.message);
// => "Oops, something went wrong"
使用throw语法,你可以抛出一个错误。
throw new Error('Oops');
当错误被抛出时,当前的执行会停止,然后在调用栈的第一个 catch 代码块中继续。
try {
throw new Error('Oops');
} catch (error) {
console.log(error.message);
// => "Oops"
}
继承是一种在类之间建立父子关系的方式。 子类(有时称为_派生类_)可以访问父类(有时称为_基类_)定义的行为和数据。
class Pet {
constructor(name) {
this.name = name;
}
introduce() {
console.log(`This is my pet, ${this.name}.`);
}
}
class Dog extends Pet {}
const dog = new Dog('Otis');
dog.introduce();
// => This is my pet, Otis.
子类声明中的extends关键字通过原型链与父类建立关系。
由子类构造函数创建的对象,其原型链中会包含父类的原型,从而可以访问父类定义的所有方法或数据。
const dog = new Dog('Otis');
Dog.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(dog); // => true
Pet.prototype.isPrototypeOf(Dog.prototype); // => true
Pet.prototype.hasOwnProperty('introduce'); // => true
Dog.prototype.hasOwnProperty('introduce'); // => false
dog.hasOwnProperty('introduce'); // => false
和 JavaScript 中的任何类一样,派生类可以使用extends关键字继承Error,从而创建自定义错误。
instanceof语法会检查捕获到的错误是否是Error某个特定派生类的实例。
class CustomError extends Error {}
try {
// ... Code that may throw an error
} catch (error) {
if (error instanceof CustomError) {
console.log('The error thrown is an instance of the CustomError');
}
}
Elena 是一家报社印刷厂的新任质量经理。她刚来到公司,就决定检查一下工厂里的一些流程,看看有什么可以改进的地方。 她发现技术人员要手工做大量的质量检查。 她觉得这是个实现自动化的好机会,于是请你这位自由职业开发者开发一个软件来监控部分机器。
你的第一个任务是写一个软件来监控生产车间的湿度。公司的软件上已经连接了一个传感器,它会定期返回房间的湿度百分比。
你需要在软件中实现一个函数,当湿度百分比过高时抛出一个错误。
这个函数应该叫 checkHumidityLevel,接受湿度百分比作为参数。
如果百分比超过 70%,你就应该抛出一个错误(错误信息是什么并不重要)。
checkHumidityLevel(60);
// => undefined
checkHumidityLevel(100);
// Throws an error
Elena 对你的第一项任务非常满意,于是让你负责监控机器的温度。 在和一位名叫 Greg 的技术人员聊天时,你得知如果机器的温度超过 500°C,技术人员就会开始担心过热。
机器上装有一个测量其内部温度的传感器。 要知道,这个传感器非常灵敏,经常坏掉。 这种情况下,技术人员就需要更换它。
你的任务是实现一个函数 reportOverheating,它接受温度作为参数,并在传感器损坏或机器开始过热时抛出一个错误。
因为之后你需要根据不同的错误做出不同的反应,所以需要一种机制来区分这两类错误。
你可以依靠错误信息来判断,但这样会让代码变得脆弱,一旦信息被更新就会失效。
所以为了能正确地做到这一点,你要抛出不同错误类的实例。
null。
这种情况下,你应该抛出一个 ArgumentError。OverheatingError。
这个错误类在实例化时会接受一个温度参数。
确保你抛出的 OverheatingError 带有一个 temperature 属性。reportOverheating(null);
// Throws an ArgumentError
reportOverheating(800);
// Throws an OverheatingError
现在你的机器已经能检测错误了,你要实现一个函数,让它对这些错误做出不同的反应:
实现一个函数 monitorTheMachine,它接受一个参数 actions。
actions 是一个对象,有 4 个属性:
| 属性 | 说明 |
|---|---|
check |
一个 函数。检查机器的温度。可能会抛出各种错误。 |
alertDeadSensor |
一个 函数。提醒技术人员,温度传感器已经损坏。 |
alertOverheating |
一个 函数。会打开机器上的警示灯。 |
shutdown |
一个 函数。会关闭机器。 |
monitorTheMachine(actions) 函数应该在内部调用 check()。
如果调用通过,这个函数不应返回任何内容。
如果它throw了一个错误,则会有不同的预期行为:
| 异常 | 预期行为 |
|---|---|
ArgumentError |
调用 alertDeadSensor 函数。 |
OverheatingError |
执行过热处理流程。 |
| (其他任何情况) | 重新抛出该错误 |
过热处理流程
如果温度低于 600 °C,就调用 alertOverheating 函数打开警示灯。
如果温度超过 600 °C,情况就很危急,所以要调用 shutdown 函数。
monitorTheMachine({
check,
alertDeadSensor,
alertOverheating,
shutdown,
});