5 ways to eliminate if/else/switch/case in JavaScript
5 ways to eliminate if/else/switch/case in JavaScript
最近开始使用JavaScript. 回顾了一下这几天的代码, 发现圈复杂度为1. 30几个函数40多行, 超过两行的函数都很少 (当然那种当做对象来用的函数除外, 只说实际做事的函数. 不要小看这40几行代码, 完成了5个完整的具有用户价值的功能. JavaScript的表达能力不是盖的).
由于JavaScript具备一些函数式编程语言的特征, 写出没有分支没有显式循环的代码也属正常. 但实际上多数代码还是命令式的. 命令式风格也能写出圈复杂度为1的代码, 看看都用到了哪些技巧.
多态
这种技巧在<<重构>>里提过, 跟JavaScript没有多大关系. JavaScript对Duck Typing的支持, 使得多态更容易实现. 略过
Null Object Pattern
这个也跟JavaScript没多大关系. 具体到js, 简单说就是不要出现undefined和null, 总是赋初值. string赋””, 对象赋{ }, 等等, 可以少很多判断
Dispatch Earlier, or “Boolean Parameter Considered Harmful”
这也是一种语言无关的策略. 多说几句. 简单来说就是但凡在函数内部需要根据参数进行判断走不同分支的时候, 总应该存在一个更早的时机可以把执行路径分开, 从而消除判断. 或曰早一点分开也需要判断啊! 这是对的, 但这个判断可以由用户做出, 或者在程序的配置中做出, 而无需运行时逻辑. 举个简单的栗子: 用户点击网页对话框中的”确定”和”取消”时发给server端的请求应该如何设计?
一种是发送请求到如下URL: http://my.domain/some/question?agreed=1 或者 http://my.domain/some/question?agreed=0或者post的话同一个URL不同body. 如果是这种设计, 那server端必然有一个if来判断是确定还是取消. 可用户点击的时候已经做出判断了啊, 在程序中再做一次不是很多余吗?
另一种设计会利用用户的判断, 点击”确定”或”取消”的请求会被发送到不同的URL, 从而被路由到不同的server端的代码. 处理”确定”的代码无需关心用户点击的是不是”确定”, 因为只有用户点击”确定”后请求才会被送到你那里. 类似桌面应用不同的按钮关联不同的事件处理程序.
那会不会有代码重复? 有就抽出来呗.
JavaScript 对象是天然的分发表
只有这一条跟JavaScript有点关系. JavaScript对象就是以string为key的哈希, 而JavaScript中函数可以作为值, 也就是函数可以作为哈希的value. 这让JavaScript对象成了一个天然的分发表, key进去,函数出来, 不用任何显式的if/else/switch. 举个栗子:
即时聊天机器人, 根据用户的输入做不同的动作, 比如输入天气的话, 就去查询最近的天气并返回, 输入餐馆就查询附近的餐馆并返回