js switch case语句_你可能不需要在 JavaScript 使用 switch 语句

没有 switch 就没有复杂的代码块

switch很方便:给定一个表达式,我们可以检查它是否与一堆case子句中的其他表达式匹配。考虑以下示例:

const name = "Juliana";switch (name) {  case "Juliana":    console.log("She's Juliana");    break;  case "Tom":    console.log("She's not Juliana");    break;}

当 name 为**“Juliana”**时,我们将打印一条消息,并立即中断退出该块。在switch函数内部时,直接在 case 块使用 return,就可以省略break。

当没有匹配项时,可以使用 default 选项:

const name = "Kris";switch (name) {  case "Juliana":    console.log("She's Juliana");    break;  case "Tom":    console.log("She's not Juliana");    break;  default:    console.log("Sorry, no match");}

switch在 Redux reducers 中也大量使用(尽管Redux Toolkit简化了样板),以避免产生大量的if。考虑以下示例:

const LOGIN_SUCCESS = "LOGIN_SUCCESS";const LOGIN_FAILED = "LOGIN_FAILED";const authState = {  token: "",  error: "",};function authReducer(state = authState, action) {  switch (action.type) {    case LOGIN_SUCCESS:      return { ...state, token: action.payload };    case LOGIN_FAILED:      return { ...state, error: action.payload };    default:      return state;  }}

这有什么问题吗?几乎没有。但是有没有更好的选择呢?

从 Python 获得的启示

来自 Telmo 的这条 Tweet引起了我的注意。他展示了两种“switch”风格,其中一种非常接近Python中的模式。

Python 没有开关,它给我们一个更好的替代方法。首先让我们将代码从 JavaScript 移植到Python:

LOGIN_SUCCESS = "LOGIN_SUCCESS"LOGIN_FAILED = "LOGIN_FAILED"auth_state = {"token": "", "error": ""}def auth_reducer(state=auth_state, action={}):    mapping = {        LOGIN_SUCCESS: {**state, "token": action["payload"]},        LOGIN_FAILED: {**state, "error": action["payload"]},    }    return mapping.get(action["type"], state)

在 Python 中,我们可以使用字典来模拟switch 。dict.get() 可以用来表示 switch 的 default 语句。

当访问不存在的key时,Python 会触发一个 KeyError 错误:

>>> my_dict = {    "name": "John",     "city": "Rome",     "age": 44    }>>> my_dict["not_here"]# Output: KeyError: 'not_here'

.get()方法是一种更安全方法,因为它不会引发错误,并且可以为不存在的key指定默认值:

>>> my_dict = {    "name": "John",     "city": "Rome",     "age": 44    }>>> my_dict.get("not_here", "not found")# Output: 'not found'

因此,Pytho n中的这一行:

    return mapping.get(action["type"], state)

等价于 JavaScript中的:

function authReducer(state = authState, action) {  ...    default:      return state;  ...}

使用字典的方式替换 switch

再次思考前面的示例:

const LOGIN_SUCCESS = "LOGIN_SUCCESS";const LOGIN_FAILED = "LOGIN_FAILED";const authState = {  token: "",  error: "",};function authReducer(state = authState, action) {  switch (action.type) {    case LOGIN_SUCCESS:      return { ...state, token: action.payload };    case LOGIN_FAILED:      return { ...state, error: action.payload };    default:      return state;  }}

如果不使用 switch 我们可以这样做:

function authReducer(state = authState, action) {  const mapping = {    [LOGIN_SUCCESS]: { ...state, token: action.payload },    [LOGIN_FAILED]: { ...state, error: action.payload }  };  return mapping[action.type] || state;}

这里我们使用 ES6 中的计算属性,此处,mapping的属性是根据两个常量即时计算的:LOGIN_SUCCESS 和 LOGIN_FAILED。属性对应的值,我们这里使用的是对象解构,这里 ES9((ECMAScript 2018)) 出来的。

const mapping = {  [LOGIN_SUCCESS]: { ...state, token: action.payload },  [LOGIN_FAILED]: { ...state, error: action.payload }}

你如何看待这种方法?它对 switch 来说可能还能一些限制,但对于 reducer 来说可能是一种更好的方案。

但是,此代码的性能如何?

性能怎么样?

switch 的性能优于字典的写法。我们可以使用下面的事例测试一下:

console.time("sample");for (let i = 0; i 

测量它们十次左右,

for t in {1..10}; do node switch.js >> switch.txt;donefor t in {1..10}; do node map.js >> map.txt;done
a8602352dfc893335292a2a83aa74ac9.png

作者:Valentino Gagliardi 译者:前端小智 来源:valentinog

原文:https://codeburst.io/alternative-to-javascripts-switch-statement-with-a-functional-twist-3f572787ba1c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值