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

  • 相关阅读:
    【转自己的落谷博客】联通块的dfs
    STL中map的简单使用&常数优化
    转自自己的关于落谷计数器【p1239】的题解
    计算机网络三种模型
    docker的常用的一些配置
    容器整体性理解
    如何在类中定义装饰器?
    如何实现属性可修改的函数装饰器?
    如何定义带参数装饰器?
    如何为被装饰的函数保存元数据?
  • 原文地址:https://www.cnblogs.com/wzndkj/p/14077572.html
Copyright © 2020-2023  润新知