throw
throw 語句會丟擲一個使用者定義的異常。當前函式的執行將停止(throw 之後的語句不會被執行),控制將傳遞到呼叫堆疊中第一個 catch 塊。如果在呼叫函式中不存在 catch 塊,程式將終止。
試一試
function getRectArea(width, height) {
if (isNaN(width) || isNaN(height)) {
throw new Error("Parameter is not a number!");
}
}
try {
getRectArea(3, "A");
} catch (e) {
console.error(e);
// Expected output: Error: Parameter is not a number!
}
語法
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® 2026 語言規範 # sec-throw-statement |
瀏覽器相容性
載入中…