你不知道的 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 为止

posted @   wzndkj  阅读(535)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2019-12-03 前端性能优化 图片相关的优化
2018-12-03 CORS跨域限制以及预请求验证
2017-12-03 事件(五):事件委托
2017-12-03 事件(四):事件类型
点击右上角即可分享
微信分享提示