throw
throw
语句用于抛出用户自定义的异常。当前函数的执行将停止(throw
之后的语句不会被执行),并且控制权将传递给��用堆栈中第一个 catch
块。如果调用函数中没有 catch
块,则程序将终止。
尝试一下
语法
js
throw expression;
expression
-
抛出表达式。
描述
throw
语句在任何可以使用语句的上下文中都有效。它的执行会产生一个在调用堆栈传播的异常。有关错误冒泡和处理的更多信息,请参阅流程控制与错误处理。
throw
关键字后面可以跟任何类型的表达式,例如:
js
throw error; // 抛出之前定义的值(例如,在 catch 块中)
throw new Error("Required"); // 抛出一个新的错误对象
在实践中,你抛出的异常应该始终是 Error
对象或 Error
子类的实例,例如 RangeError
。这是因为捕获错误的代码可能期望捕获的值具有一些属性,例如 错误信息
。例如,Web API 通常会抛出 DOMException
实例,这些实例继承自 Error.prototype
。
自动分号补全
语法不允许在 throw
关键字和要抛出的表达式之间出现换行。
js
throw
new Error();
上面的代码经过自动分号补全(ASI)转换后变为:
js
throw;
new Error();
这段代码无效,因为与 return
语句不同,throw
语句后面必须跟一个表达式。
为了避免这个问题(防止 ASI),可以使用括号:
js
throw (
new Error()
);
示例
抛出用户自定义的错误
此示例定义了一个函数,该函数在输入不是预期类型时抛出 TypeError
异常。
js
function isNumeric(x) {
return ["number", "bigint"].includes(typeof x);
}
function sum(...values) {
if (!values.every(isNumeric)) {
throw new TypeError("只能添加数字");
}
return values.reduce((a, b) => a + b);
}
console.log(sum(1, 2, 3)); // 6
try {
sum("1", "2");
} catch (e) {
console.error(e); // TypeError:只能添加数字
}
抛出一个现有的对象
此示例调用了一个基于回调的异步函数,并在回调接收到错误时抛出错误。
js
readFile("foo.txt", (err, data) => {
if (err) {
throw err;
}
console.log(data);
});
通过这种方式抛出的错误无法被调用者捕获,并会导致程序崩溃,除非:(a)readFile
函数本身捕获了错误,或(b)程序在捕获顶级错误的上下文中运行。你可以使用 Promise()
构造函数更自然地处理错误。
js
function readFilePromise(path) {
return new Promise((resolve, reject) => {
readFile(path, (err, data) => {
if (err) {
reject(err);
}
resolve(data);
});
});
}
try {
const data = await readFilePromise("foo.txt");
console.log(data);
} catch (err) {
console.error(err);
}
规范
Specification |
---|
ECMAScript Language Specification # sec-throw-statement |
浏览器兼容性
BCD tables only load in the browser