IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

JavaScript:假如default不是switch的最后一项

老赵点滴 2011-08-09 08:13:19 累计浏览 2,972 次
本机暂存

    话说大家对于switch语句应该再熟悉不过了,各种类C语言都不例外,JavaScript自然也是如此。switch的逻辑很简单,根据switch内容的值执行对应的case项,否则执行default项即可。但是不同的语言在具体一些细节上面的处理却是不同的。例如在JavaScript里,每个case项都可以没有break,于是语句便会顺延到下个case或是default里面去――但某些语言设计者认为这种特性容易造成代码理解上的偏差,因此比如在C#里便要求每个非空的case都要有个break。那么再来一个细节问题:如果default之后还有case,那么会出现什么样的情况?如果default里没有break呢?

switch (a) {
    case 0:
        console.log("0");
    default:
        console.log("default");
    case 1:
        console.log("1");
}

    就好比这段代码,当a等于0、1或2的时候,将会输出什么样的内容呢?先猜猜,别急着往下看。

    当a等于0时,则会输出:

0
default
1

    当a等于1时,则会输出:

1

    当a等于2时,则会输出:

default
1

    好吧,尽管这样的代码比较罕见,但执行结果也并没有什么“特殊”的。switch的规则依旧可以用一句话说清:如果匹配到某个case,则从该case处开始执行,否则就从default处开始执行,一直向下,直到出现break语句为止。至于default的位置是否在最后,对于执行的策略可谓完全没有影响。

    当然,我实在没想到为什么有人会写这样的代码,所以假如有人对这点感觉恍惚我也觉得没太大关系。不过既然我要写Jscex,则还是必须对此类代码的行为有所了解。尽管语言的使用者可以选择合适的子集,但语言的开发者(编译器、解释器等等)却必须遵循完整的规范,这是Jscex这类项目需要应对的麻烦。

    既然Jscex号称支持“全部JavaScript语言特性”,自然对switch的支持也在包括在内。switch的麻烦之处在于它的每个分支不像if语句那样完全相互独立,而是会不断“穿透”下去直至遇上break。因此Jscex在处理switch的时候也使用了一些技巧。例如下面这段代码:

switch (a) {
    case 0:
        $await(helloWorld());
    default:
        console.log("default");
    case 1:
        console.log("1");
}

    Jscex会将每个case及default中的语句“补齐”,以“确保”每项里都有完整的语句以及最后的break:

switch (a) {
    case 0:
        $await(helloWorld());
        console.log("default");
        console.log("1");
        break;
    default:
        console.log("default");
        console.log("1");
        break;
    case 1:
        console.log("1");
        break;
}

    然后再将其编译为:

switch (a) {
    case 0:
        return $$_builder_$$_0.Bind(helloWorld(), function () {
            console.log("default");
            console.log("1");
            return $$_builder_$$_0.Normal();
        });
    default:
        console.log("default");
        console.log("1");
        return $$_builder_$$_0.Normal();
    case 1:
        console.log("1");
        return $$_builder_$$_0.Normal();
    }
})

    自然,如果switch里没有包含bind操作(例如$await语句),则整个switch语句都会得以保留,这也是Jscex编译结果的优化策略之一。

同分类推荐文章

  1. translateZ() (2026-06-25 21:18:56)
  2. translateY() (2026-06-25 21:17:56)
  3. translateX() (2026-06-25 21:16:01)

查看更多 前端 文章 →

建议继续学习

  1. JQuery实现Excel表格呈现 (累计阅读 48,349)
  2. 深入理解Javascript之执行上下文(Execution Context) (累计阅读 18,404)
  3. 从输入 URL 到页面加载完成的过程中都发生了什么事情? (累计阅读 15,933)
  4. 图片动态局部毛玻璃模糊效果的实现 (累计阅读 14,848)
  5. 天朝第二代身份证号码的验证机制 (累计阅读 14,761)
  6. HTML 5 的data-* 自定义属性 (累计阅读 14,349)
  7. 分享一个JQUERY颜色选择插件 (累计阅读 14,223)
  8. 什么是全栈工程师? (累计阅读 14,038)
  9. 快速排序(Quicksort)的Javascript实现 (累计阅读 11,735)
  10. 7 天打造前端性能监控系统 (累计阅读 11,187)