本文转载自微信公众号“大千世界”,转载请联系大千世界公众号。没有switch就没有复杂的代码块switch很方便:给定一个表达式,我们可以检查它是否与一堆case子句中的其他表达式匹配。考虑以下示例:constname="Juliana";switch(name){case"Juliana":console.log("She'sJuliana");break;case"Tom":console.log("She'snotJuliana");break;}当name是**"Juliana"**时,我们将打印一条消息并立即跳出块。在switch函数内部,直接在case块中使用return来省略break。当没有匹配时,可以使用默认选项:constname="Kris";switch(name){case"Juliana":console.log("She'sJuliana");break;case"Tom":console.log("She'snotJuliana");break;default:console.log("Sorry,nomatch");}switch在Reduxreducer中也大量使用(尽管ReduxToolkit简化了样板)以避免很多if。考虑以下示例:constLOGIN_SUCCESS="LOGIN_SUCCESS";constLOGIN_FAILED="LOGIN_FAILED";constauthState={token:"",error:"",};functionauthReducer(state=authState,action){switch(action.type){caseLOGIN_SUCCESS:return{...state,token:action.payload};caseLOGIN_FAILED:return{...state,error:action.payload};default:returnstate;}}这有什么问题吗?几乎没有。但是有更好的选择吗?从Python中汲取灵感Telmo的这条推文引起了我的注意。他展示了两种“开关”样式,其中一种非常接近Python中的模式。Python没有开关,它给了我们一个更好的选择。首先让我们将代码从JavaScript移植到Python:={LOGIN_SUCCESS:{**state,"token":action["payload"]},LOGIN_FAILED:{**state,"error":action["payload"]},}returnmapping.get(action["类型"],state)在Python中,我们可以使用字典来模拟开关。dict.get()可以用来表示switch的默认语句。当访问一个不存在的key时,Python会触发KeyError:>>>my_dict={"name":"John","city":"Rome","age":44}>>>my_dict["not_here"]#Output:KeyError:'not_here'。get()方法是一种更安全的方法,因为它不会引发错误,并且您可以为不存在的键指定默认值:>>>my_dict={"name":"John","city":"Rome","age":44}>>>my_dict.get("not_here","notfound")#Output:'notfound'因此,Python中的这一行:returnmapping。get(action["type"],state)相当于JavaScript:functionauthReducer(state=authState,action){...default:returnstate;...}用字典代替switch再想想前面的例子:constLOGIN_SUCCESS="LOGIN_SUCCESS";constLOGIN_FAILED="LOGIN_FAILED";constauthState={token:"",error:"",};functionauthReducer(state=authState,action){switch(action.type){caseLOGIN_SUCCESS:return{...状态,token:action.payload};caseLOGIN_FAILED:return{...state,error:action.payload};default:returnstate;}}如果我们不使用switch,我们可以这样做:...state,error:action.payload}};returnmapping[action.type]||state;}这里我们使用了ES6中的computed属性,这里映射的属性是根据两个常量LOGIN_SUCCESS和LOGIN_FAILED即时计算的attributes对应的值,我们这里使用的是对象解构,它来自ES9((ECMAScript2018))。constmapping={[LOGIN_SUCCESS]:{...state,token:action.payload},[LOGIN_FAILED]:{...state,error:action.payload}}您如何看待这种方法?可能对于switch还是有一些限制,但是对于reducers来说可能是一个更好的解决方案。但是这段代码的性能如何?表现如何?开关的性能优于字典表示法。我们可以使用下面的例子进行测试:}console.timeEnd("示例");测量它们大约十次,fortin{1..10};donodeswitch.js>>switch.txt;donefortin{1..10};donodemap.js>>map.txt;完毕
