js中的try catch finally 中的return執行機制

try catch finally 子句中結合 return 會有怎樣的效果?

try catch finally 子句是 ECMA2015 - try catch statment 中定義的語法。 其執行機制以下ui

try {Block} catch 語句

  • Let B be the result of evaluating Block.
  • If B.[[type]] is throw, then Let C be CatchClauseEvaluation of Catch with parameter B.[[value]].
  • Else B.[[type]] is not throw, Let C be B.
  • If C.[[type]] is return, or C.[[type]] is throw, return Completion(C).
  • If C.[[value]] is not empty, return Completion(C).
  • Return Completion{[[type]]: C.[[type]], [[value]]: undefined, [[target]]: C.[[target]]}.

try catch 語句首先會執行try包裹的代碼塊,根據代碼塊執行結果判斷是否進入catch的代碼塊,若是catch的代碼塊有返回結果,則拋出異常時會覆蓋try語句的執行結果。不然由於Block是異常拋出,返回undefined。lua

function test (){
    try {
        return 0
    } catch (e) {
        return 1
    }
}
test() // 0
function test1 (){
    try {
        throw new Error()
        return 0 // 這裏不會執行到
    } catch (e) {
        return 1
    }
}
test1() //1
複製代碼

try {Block} finally 語句

  • Let B be the result of evaluating Block.
  • Let F be the result of evaluating Finally.
  • If F.[[type]] is normal, let F be B.
  • If F.[[type]] is return, or F.[[type]] is throw, return Completion(F).
  • If F.[[value]] is not empty, return Completion(F).
  • Return Completion{[[type]]: F.[[type]], [[value]]: undefined, [[target]]: F.[[target]]}.

Block 和 finally包裹的代碼會依次執行,同時記錄其返回結果 B 與 F,若是F 有返回值(正常或者異常返回),則返回F的結果,不然返回B的結果spa

function test (){
    try {
        throw new Error()
    } finally {
        return 1
    }
}
test() // 1
function test1 (){
    try {
        throw new Error()
    } finally {
        throw new Error();
    }
}
test1() // Uncaught Error

function test2 (){
    try {
        return 0
    } finally {

    }
}
test2() // 0

function test3 (){
    try {
        return 0
    } finally {
        return 1
    }
}

test3() // 1
複製代碼

try {Block} catch finally 語句

  • Let B be the result of evaluating Block.
  • If B.[[type]] is throw, thenLet C be CatchClauseEvaluation of Catch with parameter B.[[value]].
  • Else B.[[type]] is not throw, let C be B.
  • Let F be the result of evaluating Finally.
  • If F.[[type]] is normal, let F be C.
  • If F.[[type]] is return, or F.[[type]] is throw, return Completion(F).
  • If F.[[value]] is not empty, return NormalCompletion(F.[[value]]).
  • Return Completion{[[type]]: F.[[type]], [[value]]: undefined, [[target]]: F.[[target]]}.

至關於 try catch 和try finally 的組合執行,先執行try catch 的處理結果 再將其結果與finally合併。code

一些有意思的案例

function test() {
    var a = 1;
    try {
        return a;
    } finally {
        ++a;
    }
}
test() // 1

function test1() {
    var a = 1;
    try {
        return a;
    } finally {
        ++a;
        return a;
    }
}
test1() // 2
function test2() {
    var obj = {a:1};
    try {
        return obj;
    } finally {
        ++obj.a;
    }
}
test2().a // 2

function test3() {
    var obj = {a:1};
    try {
        return obj.a;
    } finally {
        ++obj.a;
    }
}
test1() // 1
複製代碼
相關文章
相關標籤/搜索