function foo() { try { return 42; } finally { console.log( "Hello" ); } console.log( "never runs" ); } console.log( foo() ); // Hello // 42
這裏 return 42 先執行,並將 foo() 函數的返回值設置爲 42。然後 try 執行完畢,接着執行 finally。最後 foo() 函數執行完畢,console.log(..) 顯示返回值
function foo() { try { throw 42; } finally { console.log( "Hello" ); } console.log( "never runs" ); } console.log( foo() ); // Hello // Uncaught Exception: 42
function foo() { try { return 42; } finally { throw "Oops!"; } console.log( "never runs" ); } console.log( foo() ); // Uncaught Exception: Oops!
finally 中的 return 會覆蓋 try 和 catch 中 return 的返回值:
function foo() { try { return 42; } finally { // 沒有返回語句,所以沒有覆蓋 } } function bar() { try { return 42; } finally { // 覆蓋前面的 return 42 return; } } function baz() { try { return 42; } finally { // 覆蓋前面的 return 42 return "Hello"; } } foo(); // 42 bar(); // undefined baz(); // Hello
通常來說,在函數中省略 return 的結果和 return; 及 return undefined; 在 finally 中省略 return 則會返回前面的 return 設定的返回值。
switch
var a = "42"; switch (true) { case a == 10: console.log( "10 or '10'" ); break; case a == 42; console.log( "42 or '42'" ); break; default: // 永遠執行不到這裏 } // 42 or '42'
除簡單值以外,case 中還可以出現各種表達式,它會將表達式的結果值和 true 進行比較。 因爲a == 42的結果爲true,所以條件成立。
在這裏使用 || 和 && 等邏輯運算符就很容易掉進坑裏:
var a = "hello world"; var b = 10; switch (true) { case (a || b == 10): // 永遠執行不到這裏 break; default: console.log( "Oops" ); } // Oops
因爲(a || b == 10)的結果是"hello world"而非true,所以嚴格相等比較不成立
var a = 10; switch (a) { case 1: case 2: // 永遠執行不到這裏 default: console.log( "default" ); case 3: console.log( "3" ); break; case 4: console.log( "4" ); } // default // 3
上例中的代碼是這樣執行的,首先遍歷並找到所有匹配的 case,如果沒有匹配則執行default 中的代碼。因爲其中沒有 break,所以繼續執行已經遍歷過的 case 3 代碼塊,直 到 break 爲止