異常跟順序,選擇,循環(huán),函數(shù)調(diào)用一樣,屬于控制流程之一。
異??刂婆c函數(shù)的行為有關。
# 調(diào)用棧
我們可以把函數(shù)的調(diào)用和完成行為,看作是對一個叫調(diào)用棧的順序容器的操作。
* 每一次函數(shù)被調(diào)用時,該函數(shù)的運行副本都會被加入到調(diào)用棧的頂部。
* 而調(diào)用棧頂部的函數(shù)總是執(zhí)行中的函數(shù)。
* 每一次函數(shù)執(zhí)行完畢后,就會從調(diào)用棧頂部移除。(此時位于調(diào)用棧頂部的函數(shù)就會被繼續(xù)執(zhí)行)
~~~
var funcA = function () { };
var funcB = function () {
funcA();
//...
};
funcB();
~~~
以上代碼的控制流程是:
1. 調(diào)用funcB,調(diào)用棧加入funcB。(調(diào)用棧:funcB)
2. 執(zhí)行funcB。(調(diào)用棧:funcB)
3. 調(diào)用funcA,調(diào)用棧加入funcA。(調(diào)用棧:funcB funcA)
4. 執(zhí)行funcA。(調(diào)用棧:funcB funcA)
5. funcA執(zhí)行完畢,調(diào)用棧頂部的函數(shù)被移除。(調(diào)用棧:funcB)
6. 繼續(xù)執(zhí)行funcB。(調(diào)用棧:funcB)
7. funcB執(zhí)行完畢,調(diào)用棧頂部的函數(shù)被移除。(調(diào)用棧:)
# 異常控制
* 如果一個函數(shù)在執(zhí)行中拋出了異常,函數(shù)就會被強制結(jié)束,調(diào)用棧頂部的函數(shù)也會因此被移除。并且,該異常仍會從棧頂函數(shù)繼續(xù)執(zhí)行的位置處拋出。
* 如果一個異常被捕捉,調(diào)用棧中的函數(shù)會在異常處理后繼續(xù)工作。
在ES中,使用關鍵字**throw**主動拋出一個異常,使用關鍵字**try**捕捉一個語句塊里的異常,使用關鍵字**catch**處理捕捉到的異常。
~~~
var func = function () {
throw "func";
}
try {
func();
}
catch (e) {
console.log(e);
}
console.log('On working.');
~~~

ES還提供了一個處理異常的關鍵字**finally**,在finally語句塊中的代碼,無論異常發(fā)生與否都會被執(zhí)行。
甚至從catch中拋出了異常,finally仍然會被處理。
~~~
try {
throw {};
}
catch (e) {
throw e;//相當于在函數(shù)中繼續(xù)拋出異常。
}
finally {
console.log("Anyway.");
}
console.log("On working.");//no~
~~~

