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

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