说到对分支的处理,写法可就多了去了。if 分支写法可以算一种,switch 分支写法可以算第二种,第三种是使用策略模式,如果要把条件运算符也算上的话,嗯,刚好四种。

不过本文的主角是 switch。大家都了解 switch 的写法一般来说是 switch 变量或表达式,case 常量。嗯,比如说,一个百分制成绩,90 及 90 分以上算优秀,80 及以上 90 以下算良好,60 及以上 80 以下算合格,60 以下为不合格,用 switch 大概会这么写:

function calcGrade(score) {const line = score / 10 | 0;switch (line) {case 10: case 9:return "优秀";case 8:return "良好";case 7: case 6:return "合格";default:return "不合格";}
}

代码中 score / 10 | 0Math.floor(score / 10) 是一样的效果,就是除以 10 取商的整数部分。

这段 switch 用得中规中矩,用取整的办法来避免使用一长串 if … else 分支也算是取了巧。

但是现在规则改了,将合格和良好的分隔点从 80 分降到 75 分,该怎么办?

按上面取整的办法依然可以,不过这次除数不再是 10,而是 5。相应地,case 也多了很多:

  • 18、19、20 是优秀
  • 15、16、17 是良好
  • 12、13、14 是合格
  • 剩下的是不合格

写 9 个 case,真不如用 if … else 算了。

是吗?其实用 switch 也有简单一些的写法:

function calcGrade(score) {switch (true) {case score >= 90:return "优秀";case score >= 75:return "良好";case score >= 60:return "合格";default:return "不合格";}
}

是不是感觉有些奇怪?这完全不是习惯了的 switch 表达式 case 常量,而是正好相反,switch 常量 case 表达式!如果你拿这段程序去跑一下,会发现一点问题都没有。因为——switchcase 是按 === 来匹配的,它并不在乎是表达式还是常量,或者说,switch 和 case 后面都可以接表达式!

JavaScript 里一切都可以是表达式 …… 如果不是,用 IIFE 封装一个就是了

function calcGrade(score) {return (value => {switch (true) {case value >= 90:return "优秀";case value >= 75:return "良好";case value >= 60:return "合格";default:return "不合格";}})(score);
}

注意这里把 score 作为 IIFE 的参数,是因为在实际使用中,可能需要传入的是一个表达式。这种情况下应该提前求值,而且只求一次(避免替在的副作用)。

不过这样的封装显然没什么意义,如果真要这样封装,不如封成策略:

function calcGrade(score) {return ((value, rules) => rules.find(({ t }) => t(value)).v)(score,[{ t: n => n >= 90, v: "优秀" },{ t: n => n >= 75, v: "良好" },{ t: n => n >= 60, v: "合格" },{ t: () => true, v: "不合格" },]);
}

每项策略都是一个含有 tester (t) 和值 (v) 的对象。tester 是一个判断函数,传入需要判断的值,也就是 switch (表达式) 这里表达式,而这个表达式也是提前求值之后作为 IIFE 的参数传入的。应用策略的过程简单粗暴,就是找到第一个符合条件的策略,把它的值取出来。

当然这样用策略有点大材小用。真正需要用策略的情况,策略中通常不是一个值,而是一个行为,也就函数。

我们知道在 switch 语句中,各个 case 之间是在同一个作用域内,所以不能在两个 case 语句中声明同一个局部变量。虽然用 { } 包裹可以解决这些问题,但代码看起来不怎么好看,特别是还要注意不要忘了 break。如果用策略的话,看起来可能会顺眼一眼,也不用担心 break 的问题:

这里为了演示,在策略行为中将先输出成绩,再返回等级。

function calcGrade(score) {return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(score,[{t: n => n >= 90,fn: score => {const grade = "优秀";console.log(grade, score);return grade;}},{t: n => n >= 75,fn: score => {const grade = "良好";console.log(grade, score);return grade;}},{t: n => n >= 60,fn: score => {const grade = "合格";console.log(grade, score);return grade;}},{t: () => true,fn: score => {const grade = "不合格";console.log(grade, score);return grade;}},]);
}

代码确实有点长,因为有策略行为逻辑在里面。如果真的是要当作 switch 表达式来用的话,策略部分应该是一个表达式,不会太长的。上面的代码中,策略行为相似,可以封装成一个函数,这样就能写成表达式的形式了:

function calcGrade(score) {const printGrade = (grade, score) => {console.log(grade, score);return grade;};return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(score,[{ t: n => n >= 90, fn: score => printGrade("优秀", score) },{ t: n => n >= 75, fn: score => printGrade("良好", score) },{ t: n => n >= 60, fn: score => printGrade("合格", score) },{ t: () => true, fn: score => printGrade("不合格", score) },]);
}

JavaScript 的 switch 有四样写法,你知道么?相关推荐

  1. pow函数有四样写法,你知道吗

    求次幂是个老生常谈的话题了,在任何一门语言里都是最基础的部分.在这里主要以JS为例. 首先,最容易想到的是暴力法,也就是连续乘上n个x:但是这个的性能显然很差,我们一般不会考虑这么写.而且,为什么不用 ...

  2. 回字有四样写法之引号编码

    各种引号                 Unicode 说明 Macintosh 按键 Windows 按键 Linux (X) 按键 HTML entity   垂直单引号(兼畧缩号) ' U+0 ...

  3. 回字有四种写法,那你知道单例有五种写法吗

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 转自 ...

  4. 【转】回字有四种写法,那你知道单例有五种写法吗

    目录导航 基本介绍 写法介绍 饿汉式 懒汉式 双重检测 内部类 枚举 总结 基本介绍 单例模式(Singleton)应该是大家接触的第一个设计模式,其写法相较于其他的设计模式来说并不复杂,核心理念也非 ...

  5. JS 获取星期几的四种写法(转)

    今天是星期几的4种JS代码写法 第一种写法 var str = ""; var week = new Date().getDay(); if (week == 0) { str = ...

  6. JavaScript学习笔记(四)---闭包、递归、柯里化函数、继承、深浅拷贝、设计模式

    JavaScript学习笔记(四)---闭包.递归.柯里化函数.继承.深浅拷贝.设计模式 1. 匿名函数的使用场景 2.自运行 3.闭包 3.1前提: 3.2闭包 4.函数对象的三种定义方式 5.th ...

  7. Javascript动画效果(四)

    Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...

  8. Android代码规范----按钮单击事件的四种写法

    [前言] 按钮少的时候用第三种的匿名内部类会比较快,比如写demo测试的时候或者登陆界面之类. 按钮多的时候一般选择第四种写法. 一.第一种写法:在XML文件中声明onClick属性(很少用) 在XM ...

  9. Android点击事件(click button)的四种写法

    在学习android开发和测试的时候发现不同的人对于click事件的写法是不一样的,上网查了一下,发现有四种写法,于是想比较一下四种方法的不同 第一种方法:匿名内部类 代码: package com. ...

  10. c++ 调用system 不显示黑框_Java回调的四种写法:反射+直接调用+接口调用+Lambda表达式...

    疫情期间"闭关修炼",吃透这本Java核心知识,跳槽面试不心慌 2020"闭关"跳槽季,啃透分布式三大技术:限流.缓存.通讯 2020春招必备:MySQL(20 ...

最新文章

  1. 2020-12-18 Matlab LQR 推导及简单应用
  2. PI Function Library 应用,公共UDF开发
  3. Web开发的历史发展技术演变
  4. 知道这些面试技巧,让你的测试求职少走弯路
  5. hive臨時udf與永久udf詳細操作流程
  6. 单调栈 leetcode整理(三)
  7. 西瓜书——极大似然估计和朴素贝叶斯
  8. Linux 权限管理之基本权限
  9. 不设置DIV的宽高,让它相对于页面水平垂直居中
  10. 数据库安全之数据掩码:SQL新功能之动态数据掩码(SQL2016AZURE SQL)
  11. 图片配置文件设置 索尼a7s2_16组Sony索尼系列相机Slog2和Slog3常用Vlog灰片视频电影LTUS调色预设...
  12. STM32工作笔记045---SystemInit时钟系统初始化函数剖析
  13. 论文笔记:Deep neural networks for YouTube recommendations
  14. MATLAB图像生成函数Plot()总结
  15. 计算机技能是啥,简历中的IT技能是什么意思?
  16. TP-link与电力线通信(智能电网)
  17. css box-sizing
  18. 1.PhotoShop缩小图片的三种方式
  19. Android单元测试读写文件,Android-单元测试
  20. C语言中运算符的优先级排序表

热门文章

  1. CSS第7章上机练习1(制作QQ会员页面导航)
  2. js当前日期倒推,向前倒推或往后推算
  3. guided filter matlab,导向滤波(Guided Filter)的解析与实现
  4. 离散数学之集合笔记一
  5. Altium Designer四层板设计教程
  6. linux 韦恩图两个,nVenn:绘制广义的准比例维恩图
  7. solve函数c语言_c语言:回溯解数独程序
  8. 流水灯电路设计实验--VHDL
  9. 最后1天,购票渠道即将关闭!Unite 2018开发者大会全日程公布
  10. keil中出现警告:last line of file ends without a newline解决方法