抛出
**throw
** 语句抛出用户定义的异常。当前函数的执行将停止(throw
后的语句将不会执行),控制权将传递给调用栈中的第一个 catch
块。如果调用函数中不存在 catch
块,程序将终止。
试试看
语法
js
throw expression;
表达式
-
要抛出的表达式。
描述
throw
语句在所有可以使用语句的上下文中都有效。它的执行会生成一个异常,该异常会穿过调用栈。有关错误冒泡和处理的更多信息,请参见 控制流和错误处理。
throw
关键字后面可以是任何类型的表达式,例如
js
throw error; // Throws a previously defined value (e.g. within a catch block)
throw new Error("Required"); // Throws a new Error object
在实践中,你抛出的异常应该始终是 Error
对象或 Error
子类的实例,例如 RangeError
。这是因为捕获错误的代码可能希望在捕获的值上存在某些属性,例如 message
。例如,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("Can only add numbers");
}
return values.reduce((a, b) => a + b);
}
console.log(sum(1, 2, 3)); // 6
try {
sum("1", "2");
} catch (e) {
console.error(e); // TypeError: Can only add numbers
}
抛出现有对象
此示例调用基于回调的异步函数,如果回调收到错误,则抛出错误。
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);
}
规范
规范 |
---|
ECMAScript 语言规范 # sec-throw-statement |
浏览器兼容性
BCD 表格仅在浏览器中加载