你不知道的 JavaScript 系列中( 33 ) - try...finally 和 switch 要注意的地方
try..finally
try..finally 中finally 中的代码总是会在 try 之后执行,如果有 catch 的话则在 catch 之后执行。也可以将 finally 中的代码看作一个回调函数,即无论出现什么情况最后一定会被调用。
得到返回值的代码是在 finally 之前还是之后执行呢?
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(..) 显示返回值
try 中的 throw 也是如此:
function foo() { try { throw 42; } finally { console.log( "Hello" ); } console.log( "never runs" ); } console.log( foo() ); // Hello // Uncaught Exception: 42
如果 finally 中抛出异常(无论是有意还是无意),函数就会在此处终止。如果此前 try 中 已经有 return 设置了返回值,则该值会被丢弃:
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
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 为止