[java/javascript教程] 你会用ES6,那倒是用啊!!!

[复制链接]
查看800 | 回复0 | 2022-4-29 17:32:45 | 显示全部楼层 |阅读模式

登录网站,浏览更多精彩内容

您需要 登录 才可以下载或查看,没有账号?加入我们

×
20220429_112551_043.jpg             
  `  E" r& P( ]' C- G4 ?不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
  1. const obj = {
    7 X, ?' P: ]/ r' P; p
  2.     a:1,
    ' U0 Q1 `0 ]; d& x( u- i4 h
  3.     b:2,
    / }2 t* }$ G4 M
  4.     c:3,9 X2 `2 c4 v! ]2 k# V" ]. i
  5.     d:4,8 B' H6 {8 _, l, ]% c0 |0 w) P5 u
  6.     e:5,( c- C! S9 |1 K3 |+ y" I" Y2 F
  7. }
复制代码

" R  k# a9 w2 o9 S% k吐槽:
* D! w8 g, z; d; Y
  1. const a = obj.a;  B6 A2 V3 s8 k3 O" W& K; p
  2. const b = obj.b;  t2 \& X! h7 }# l! U0 q; `! {
  3. const c = obj.c;. g/ u; m6 u( h  b$ b, e9 H/ _( \. p
  4. const d = obj.d;& U+ Z" W" z+ U# o7 s9 {
  5. const e = obj.e;
复制代码
4 ]* x% r1 L4 a7 C# R
1 H& _% q+ A3 Y0 g/ z
或者
" u( @; j6 s! y5 S; N
  1. const f = obj.a + obj.d;
    - q$ b* |- O% D  k$ [# b
  2. const g = obj.c + obj.e;
复制代码

8 T) k5 I3 H. S0 D7 p+ J吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.1 r, v* Q/ T- C2 X+ F- N
”改进:2 z- S4 r8 j- q) Z8 J$ A
  1. const {a,b,c,d,e} = obj;3 c3 _4 F8 l0 s& h6 A. V
  2. const f = a + d;
    ; w9 u0 \" C( ]! Q3 z3 b, Q" ]& C
  3. const g = c + e;
复制代码

8 U$ k* u, ~& Y! W6 O, M8 b) j反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:' K& L% ~5 F2 K( K/ ^' y, g! p: d
  1. const {a:a1} = obj;+ f. g: i) p7 n
  2. console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
    % ?% i  H3 x% q! p
  3. const {a,b,c,d,e} = obj || {};
复制代码
: g+ B! `! G/ Q: E: a/ D8 P% n
二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];
* k7 ~: i5 F3 a
  1. const b = [1,5,6];' C* |7 K6 R3 l* F9 I
  2. const c = a.concat(b);//[1,2,3,1,5,6]" n; t3 i" ~0 w7 _7 e
  3. const obj1 = {
    % d, c9 d7 p& A9 _
  4.   a:1,' Y! B- A2 \' x7 b6 H/ L
  5. }* {- r' z: w$ H& z
  6. const obj2 = {' Z+ \. T& v) q, E: @. E
  7.   b:1,+ E4 v" g" i$ j( N; v/ P/ \: J
  8. }& L0 {1 b' c1 w7 D1 G4 }+ ?
  9. const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];# Y$ u; H1 o$ ~6 k' P
  10. const b = [1,5,6];9 C$ |2 [0 L! z& X
  11. const c = [...new Set([...a,...b])];//[1,2,3,5,6]; v3 C4 o. h4 i0 `
  12. const obj1 = {0 ~! o6 C4 h+ G/ ~% `1 Q7 E7 T
  13.   a:1,/ f2 W/ |# Z, t
  14. }
    9 t1 [; J; p2 E( w! B9 ~
  15. const obj2 = {
    4 b/ G! p2 l6 W2 V" _1 e
  16.   b:1,
    1 y* y. J: l( F5 h
  17. }( e/ S+ m: e# d, Q
  18. const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码

  e- r! i3 q; G* U* [. R7 |7 m, Z三、关于拼接字符串的吐槽8 y. ?" ~0 }5 V. A- E4 [% E3 ^" Z
  1. const name = '小明';
    # U. y! |8 @8 F/ s0 m# V( s
  2. const score = 59;/ i. q( s/ ^2 ]
  3. let result = '';
    & Z7 L. @6 e. ]5 {
  4. if(score > 60){7 X: _1 n! i* n, C$ K
  5.   result = `${name}的考试成绩及格`;
    # E8 @% i& S9 J! w" Z
  6. }else{' C9 d! U; B* G7 D3 ^% W3 u: C& ?
  7.   result = `${name}的考试成绩不及格`;
    * \' P$ s  \, m# V0 n' U' W# Z
  8. }
复制代码
' D  Q  _9 R8 m( g/ X$ S: T: [! |, M

; G  S7 e, U) w$ s: q; t吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';1 Y! k  W0 p2 S+ W4 p) Y: q
  1. const score = 59;
    5 c' s4 g/ h( E  A3 O4 J' K0 k
  2. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码

8 \, L; q/ t% W, J% e四、关于if中判断条件的吐槽if(
/ b' F& E+ B% E* }" g$ @( O0 u
  1.     type == 1 ||
    ) n7 C2 N2 e$ b* p' B8 S# h
  2.     type == 2 ||
    : X! c! c5 P: l
  3.     type == 3 ||
    ! Q# Y* c& ?7 E# }
  4.     type == 4 ||& W' T  A. }! x) [
  5. ){& Y$ ]$ \/ v$ @6 @
  6.    //...
    $ x2 N3 r6 c: h5 X
  7. }
复制代码
2 Z$ G  o- l9 O6 U& ?0 P
吐槽ES6中数组实例方法includes会不会使用呢?9 u7 G" w, k# ^" d# O
改进const condition = [1,2,3,4];
& |* @2 D+ r" f+ \( ]- ]' R/ ]+ \
  1. if( condition.includes(type) ){
    ' _  n6 C- h" k3 Z" m" Q1 U* u5 ^
  2.    //...
    9 r5 L! w( \9 Y4 \/ S5 B7 j, C+ w
  3. }
复制代码

7 y! Q; |  k* O五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
6 i3 U  q5 F; o6 T
  1. const result = a.filter( : n( e  a! R/ j" b% r' @% F6 F+ B2 ?
  2.   item =>{5 b' ?. Z) e) p! F
  3.     return item === 3
    & Z$ [4 n9 D* _! J) W
  4.   }1 _  g2 b: E/ F5 D3 K7 _
  5. )
复制代码
& G2 K  _8 `# D% ~: t
吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];7 K+ ~, V  C0 ?; a) e3 f
  1. const result = a.find(
    ( F6 [/ _5 C% C9 {) {. |
  2.   item =>{
    / [$ [6 X4 `; V  g
  3.     return item === 31 s; b& D- O- \6 `9 h" J+ f' b, L
  4.   }
    - g( k3 v1 {6 C+ [& |
  5. )
复制代码
. t. I& Q' x3 H) j  X) L5 S+ ?
- b) K# c4 m! z& W+ \  g7 _% A
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。7 C0 {9 D/ D9 x, \3 P' x; b. P& T6 {; ?
  1. const deps = {
    $ D& h3 i1 K, d7 u  R$ O
  2. '采购部':[1,2,3],
    + y6 s2 i" s- h" _& X
  3. '人事部':[5,8,12],7 l* _' j$ D8 S' f7 Z- L
  4. '行政部':[5,14,79],
    : X0 |0 }' e( h9 E
  5. '运输部':[3,64,105],7 y9 V; }9 [4 x) B" n8 y: ?
  6. }
    ! ~8 o: e) L/ k: I/ ]8 |! }
  7. let member = [];: {) u; r' Q; q* Y: J- b
  8. for (let item in deps){; ?5 n* K. e% W
  9.     const value = deps[item];" M  W, d. @& W
  10.     if(Array.isArray(value)){
    : e3 t! l* e3 c* G) a- E9 a, C
  11.         member = [...member,...value]
    0 V; E+ `) |/ k9 l  G
  12.     }
    . g7 w# b4 k8 N+ A
  13. }
    - I$ K" L! R3 |! j
  14. member = [...new Set(member)]
复制代码

6 }, ?+ T6 `' b( Z
  g9 J8 t( ?, G3 @吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?/ Q( k. E1 I! q5 n/ o9 o
改进
  l* E* I8 B) D( ]% [3 p2 x
  1. const deps = {
    ; n" x8 ]1 C! }9 ^4 @* h9 W! b
  2.     '采购部':[1,2,3],& Z0 x, l6 g' {
  3.     '人事部':[5,8,12],
    9 E" b" h4 A8 a  _1 j/ C% f5 L) E
  4.     '行政部':[5,14,79],
    0 N" O3 v# R$ ^# w. e" ]
  5.     '运输部':[3,64,105],- @  G9 f: [3 w: \" A! K+ @
  6. }
    8 g: M* V2 R- L3 e' U+ y
  7. let member = Object.values(deps).flat(Infinity);
复制代码

5 `: H0 e; h9 E6 V+ o% f/ ~# Y! k其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
3 l% w9 x0 _' w
  1. let index = 1;; i0 _8 ?# a; W6 z: I( o" C4 c( }  p
  2. let key = `topic${index}`;" ^" j6 x8 R+ F$ }: h+ T
  3. obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};; |) e- n/ ]' D8 A. R3 N& v) {
  4. let index = 1;/ z! {% i( P# H3 m( o% ^( ^
  5. obj[`topic${index}`] = '话题内容';
复制代码

  v7 ~! ^4 }4 q% h$ X+ c: M0 |& ^: r$ a! \3 ?, O
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){# ?: K/ a) W- d9 J: `+ _+ j" @- D
    //...' v) W, K  p0 h, G) K' t1 O
}
9 [$ e3 K0 b0 ^. y* I吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
' L7 W+ g5 l' U' @9 T; o" _if((value??'') !== ''){- Y+ W: O* s) }$ z/ h; Z" p# q, `
  //...
( f. e4 U0 I" Q) V8 Y9 C& ]}" a& R; ?6 L. ?6 }0 v
十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。
% R+ G$ X: u0 e6 C
  1. const fn1 = () =>{
    ) S3 B. p5 [/ }) b8 U) ^
  2.   return new Promise((resolve, reject) => {
    6 {' F/ `! x. {3 h' {8 f
  3.     setTimeout(() => {
    , \. \! x- G) T& O4 y
  4.       resolve(1);
    , Q0 H$ m7 b! X
  5.     }, 300);% b) }+ L+ C$ s4 ?
  6.   });
    - C& `: s- R6 V0 m4 ^1 V
  7. }
    4 M# l- r' ]2 [  h& q- ?- Z
  8. const fn2 = () =>{
    + E' i4 {4 T5 n6 ^# r" g1 p6 s
  9.   return new Promise((resolve, reject) => {
    - H: [6 V) O# T" A6 m
  10.     setTimeout(() => {
    & Z1 |- w4 H0 p/ k
  11.       resolve(2);
    2 T7 l9 ?& T5 g9 O% J6 x! n
  12.     }, 600);/ _9 x, J; ?" d) T! K% A
  13.   });% v; [- u5 \( V5 {9 j, p
  14. }+ z* k# v3 Q* s$ s$ C- Z$ V
  15. const fn = () =>{
    . P+ \" [6 H& R& O6 w
  16.    fn1().then(res1 =>{
    0 U0 i# U2 ^% M/ E2 A) W' ^
  17.       console.log(res1);// 1
    / v  y+ t  \& F
  18.       fn2().then(res2 =>{. R- V( J1 U" W9 o9 N$ n- ?6 r7 W7 [
  19.         console.log(res2)
    8 O- ]1 T! O6 z+ I* E. ^- C
  20.       })
    $ w- G! |2 x1 d5 }$ x
  21.    })7 j% K- i; _9 _; s* P( P- A
  22. }
复制代码

% x+ n7 ]1 ?7 [. A- I吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进
6 p" i( t% j6 j  O7 @  _
  1. const fn = async () =>{
    ; ~' |% r9 u( [9 e1 t
  2.   const res1 = await fn1();( O5 e, B* z7 _
  3.   const res2 = await fn2();
    # A& I/ }2 `/ T& o: F
  4.   console.log(res1);// 1; Q7 z* e  U3 }- {2 W: m
  5.   console.log(res2);// 2! w! E  d( a/ _
  6. }
复制代码
$ ^8 k" S% K# c
补充但是要做并发请求时,还是要用到1 p. M3 T8 Q* |4 I1 y2 L7 Y/ _
  1. Promise.all()
    9 ^/ e; p5 Y8 e$ K+ ]  b
  2. const fn = () =>{
    . ]& O' e1 y+ a' n$ ]
  3.    Promise.all([fn1(),fn2()]).then(res =>{
    : R: V6 N8 i- p  }+ V6 }( z5 X
  4.        console.log(res);// [1,2]
    " W5 ~% e3 c6 W! U
  5.    }) + z  b. `& V/ O* Z0 @
  6. }
复制代码

8 m! X# T% T+ W$ O如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
1 h; r7 c) f1 T6 {! O3 E十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。
0 X. O+ [0 \/ |8 w/ N9 {6 v
3 J9 V3 c: T" L
4 N3 i0 V( C" A1 m# x7 G1 U6 d# h+ c2 e( h! u3 \' A; s
中国领先的数字技术资源交流中心!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

5

主题

4

回帖

199

积分

学徒

积分
199
学费
176