zoukankan      html  css  js  c++  java
  • 你可能不需要在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 来说可能是一种更好的方案。

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

    广州vi设计公司 http://www.maiqicn.com 我的007办公资源网 https://www.wode007.com

    性能怎么样?

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

    console.time("sample");
    for (let i = 0; i < 2000000; i++) {
      const nextState = authReducer(authState, {
        type: LOGIN_SUCCESS,
        payload: "some_token"
      });
    }
    console.timeEnd("sample");

    测量它们十次左右,

    for t in {1..10}; do node switch.js >> switch.txt;done
    for t in {1..10}; do node map.js >> map.txt;done
  • 相关阅读:
    【原】Ubuntu13.04安装、卸载Gnome3.8
    【原】安装、卸载、查看软件时常用的命令
    【原】中文Ubuntu主目录下的文档文件夹改回英文
    【原】Ubuntu ATI/Intel双显卡 驱动安装
    【转】Hadoop vs Spark性能对比
    【译】Spark调优
    【转】Spark源码分析之-scheduler模块
    【转】Spark源码分析之-deploy模块
    【转】Spark源码分析之-Storage模块
    【转】弹性分布式数据集:一种基于内存的集群计算的容错性抽象方法
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/13679067.html
Copyright © 2011-2022 走看看