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

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

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

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

×
20220429_112551_043.jpg             6 A; A" D6 w  z
不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
  1. const obj = {: I6 K* h* k" u1 b2 x
  2.     a:1,
    5 T3 ]6 P/ b: P. Y/ Q  r/ K* Y; n
  3.     b:2,
    ) P+ T, k' w0 U/ r8 A; |
  4.     c:3,) m& L4 @4 h0 C( M! Q' Z# a6 u
  5.     d:4,
    2 p( {9 L& ?  W0 _3 p, D4 h1 A
  6.     e:5,' w1 g% n- m) J3 l2 n
  7. }
复制代码
! {7 _' W/ Y$ a3 ~
吐槽:
. t% _# U! Z+ E" E- E
  1. const a = obj.a;9 v3 u! C+ W+ s% p
  2. const b = obj.b;
    * q; w% h2 o0 B" g: b
  3. const c = obj.c;
    3 N. r  Q+ @$ Q% C
  4. const d = obj.d;! B" @3 ]4 b2 O+ X& Z, z; g
  5. const e = obj.e;
复制代码

* a- Y3 T5 e3 a7 _( H, P7 Y  U. k5 E2 T
或者
9 P3 v& f( A) R
  1. const f = obj.a + obj.d;
    2 W9 G# A8 b; f' G1 ]- R: H, N
  2. const g = obj.c + obj.e;
复制代码

% {- G3 O  H( }# i# k吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名./ B8 i, O( g; C; l8 O
”改进:
6 ?5 \' `% x0 s) h8 Y9 m
  1. const {a,b,c,d,e} = obj;
    , O( W: C; u# ?9 |% m+ a
  2. const f = a + d;
      z6 g2 A+ E: C4 i% U, }
  3. const g = c + e;
复制代码
0 O( x0 C: v: u7 A! W% d
反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:
# J+ |/ ]1 W  W4 j4 E
  1. const {a:a1} = obj;
    3 p8 T& z# q/ b( I$ `: m+ z9 A
  2. console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。/ F2 q5 d7 l4 x# j+ Z$ w
  3. const {a,b,c,d,e} = obj || {};
复制代码

, J2 M  r" b0 t; \: X; Y二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];8 u) u* w0 E  `# Q7 z. Z- q) W$ z
  1. const b = [1,5,6];
    0 {9 o' Y. x8 ?; y& Q! i- m' ?# R" D
  2. const c = a.concat(b);//[1,2,3,1,5,6]4 U/ F/ T; ?$ U5 S4 ~9 ^
  3. const obj1 = {
    % |- T- r* W: b( \0 y: Y
  4.   a:1,
    2 m7 a4 t; i5 p3 ?3 j& ]0 e
  5. }
    , M. M1 g; D8 t$ N% r% n4 l
  6. const obj2 = {
      @0 Q, T- b; h( u/ J
  7.   b:1,/ J% G* h5 a  R5 Z6 b4 W
  8. }6 W& r7 ]0 d% w  T
  9. const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];7 y$ g8 K1 T% [4 K8 n7 M. o
  10. const b = [1,5,6];6 y3 b6 Y8 T6 |$ m
  11. const c = [...new Set([...a,...b])];//[1,2,3,5,6]
    1 r5 u' t: F# b0 U. I
  12. const obj1 = {
    ' o' K5 I) I0 b' \. _
  13.   a:1,
    3 d. {* Z% R$ z
  14. }% o/ ?- ?2 w, q% E3 w- b9 c
  15. const obj2 = {7 W) `' T7 v: E& F) L1 W. P
  16.   b:1,
    3 Z* R) x6 a  Q' [# ]/ z
  17. }* I( O& a6 i# P2 H
  18. const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
& }- {2 d# z' j, U; k, C
三、关于拼接字符串的吐槽# x8 K7 d; P* k" V5 N% u+ s
  1. const name = '小明';
    4 ]) B# \0 K/ {9 n
  2. const score = 59;7 T3 V1 X; |$ }% t; m/ @
  3. let result = '';- L/ C5 Y6 s: e4 g, m: h3 e0 f
  4. if(score > 60){
    3 Q  e$ [5 z3 H  Q; e  q: F5 a- }& G
  5.   result = `${name}的考试成绩及格`; - v/ g% O) d% ^/ n# w
  6. }else{* [$ N* F# c7 o4 o3 E0 _
  7.   result = `${name}的考试成绩不及格`; * f+ e# Q% K8 I- Y- F' J
  8. }
复制代码
- E4 o; p/ h  e& e
( u- z) J' [( B% X8 B6 G
吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';
( x' D( Q8 r$ n! r" Q# G: V1 G
  1. const score = 59;) H7 a' o$ E; v) i
  2. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码
% A- X9 @0 `. k  J( f4 x
四、关于if中判断条件的吐槽if(, G2 ~& u9 J8 c1 B7 @
  1.     type == 1 ||
    2 ~  V  M! a) d9 p, x, ~% a
  2.     type == 2 ||
      u! [* q) h# |1 E2 o5 f& z, |
  3.     type == 3 ||
    ) R) X5 r' \4 j# p* d2 k0 q
  4.     type == 4 ||' }9 T- J  h* L$ I0 ]1 A
  5. ){( A% h6 i" l0 d9 ~) Y' m$ b
  6.    //...% h+ w# m0 \, I6 W( j2 u
  7. }
复制代码
3 v% L: i$ j. t, j8 z3 u2 e
吐槽ES6中数组实例方法includes会不会使用呢?
( ]6 V' A! I# B1 k# K. b/ z改进const condition = [1,2,3,4];5 ^  l) @  k4 @& _' B
  1. if( condition.includes(type) ){
    / e6 J. x' h" k
  2.    //..." u5 r, `. c  N% Y; D
  3. }
复制代码
: j' f1 x) x, V
五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
$ O" ]+ G# U0 v: ?
  1. const result = a.filter( / j: u5 H; C8 ~/ J1 P8 a' c3 G
  2.   item =>{/ ~1 F. f" n" }9 D* ]
  3.     return item === 3  e: ^: Y. H% o
  4.   }
    , W; i8 C% e' P2 w3 D9 {; P7 M. ]) }
  5. )
复制代码

9 W9 _/ F" v; O* w/ }吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];% T$ [! l4 q! w
  1. const result = a.find( 0 f0 S. n4 s" z! ], U
  2.   item =>{9 i% i1 W+ K1 e" F
  3.     return item === 3
    ; i) R  A& N3 m7 V* V3 ?: G
  4.   }. t5 S4 G; ~- n- h& {4 W
  5. )
复制代码

3 n2 _. J2 q- J' o
2 W; b; K& C3 w- p. q六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。
: O% [( Z3 t  n0 I
  1. const deps = {4 i& @( j% t& p5 o8 l& P7 y
  2. '采购部':[1,2,3],
    ; u1 r; e/ b; b( l, Y4 R4 R
  3. '人事部':[5,8,12],
    : a; T' N: Q* f& r. t3 V4 w
  4. '行政部':[5,14,79],. _% l. j  V0 B) t+ N. H+ [: j& L
  5. '运输部':[3,64,105],+ U6 P: M7 f7 ^6 U- x# E
  6. }! b" l2 t5 u8 R9 d/ m& a- _2 \
  7. let member = [];. C1 T: h1 }0 J3 o* d% h
  8. for (let item in deps){, Z8 E' K& ?2 H% U
  9.     const value = deps[item];6 m; r: |; _& Y, h5 @0 O+ U6 l
  10.     if(Array.isArray(value)){
    $ o7 T' w: R% D
  11.         member = [...member,...value]) ]3 k8 J# |- H+ ?# p! l' e' g
  12.     }" O) M5 ~' @7 R- o1 G
  13. }+ j# j  h1 o. E
  14. member = [...new Set(member)]
复制代码
2 q1 H7 _( U% m8 B
4 d7 H5 ^+ f- @. i, x9 S$ ]/ z/ z
吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
8 D$ a9 y) H/ T" }" I+ Y- y# u: Z改进: E3 M$ c6 Z! T/ ?: T4 ~
  1. const deps = {
    4 g+ c0 ]# D. w: @
  2.     '采购部':[1,2,3],
    ( J" J9 B5 F/ K& v; m0 ?; R2 o
  3.     '人事部':[5,8,12],
    ( _) I- ^* a7 k: C$ W& s
  4.     '行政部':[5,14,79],
    * Z) z8 ^) \0 Q5 s( k
  5.     '运输部':[3,64,105],. C0 b3 D8 i# V& {! C
  6. }
    . T  V. U9 N5 j) \/ f
  7. let member = Object.values(deps).flat(Infinity);
复制代码
# a4 f: d7 p0 |0 w
其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
" T% y6 u0 g3 K3 m) X, C9 b
  1. let index = 1;
    8 I2 J2 X( L! ?3 d+ o
  2. let key = `topic${index}`;8 n* X+ X  v0 w
  3. obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};
    5 ]  b6 ]" a. ]; h% U# t& S
  4. let index = 1;8 C  }/ u4 l+ t9 f+ {1 }
  5. obj[`topic${index}`] = '话题内容';
复制代码

; x7 O; z/ L3 X5 W2 Y9 C( S+ S7 g; H, [- R& o' F7 D( i
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
: A. f% a6 e* F    //...
7 K. h7 P# q. _3 r}
2 {& E* Q/ G9 P: H' X/ l: ?1 O吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?: P" j1 @2 Z: p. `; p+ L0 P
if((value??'') !== ''){
% C* R. H9 P8 K3 l+ ?2 ]  //...2 q! Q, X' v1 A
}
8 a0 V& p- H1 q十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。7 _( e6 s2 D9 C  M1 D* F3 L. V1 n8 U( y
  1. const fn1 = () =>{' w6 t# S  v9 ]4 K
  2.   return new Promise((resolve, reject) => {/ a3 Q" m! H8 a5 J0 [6 i9 Q
  3.     setTimeout(() => {
    : p6 o( y$ a; Z5 D
  4.       resolve(1);$ e, K6 g8 r$ x
  5.     }, 300);/ }$ M( ]# y, C7 d9 q/ ^4 ?$ B" K' Q
  6.   });
    7 W1 L* b: {. m; A6 h! P
  7. }
    # y( R/ J* k; C6 k
  8. const fn2 = () =>{
    ( e8 _, h( R7 S7 p( T' f
  9.   return new Promise((resolve, reject) => {/ V5 ^  ?& [; ?$ J  I  X9 [
  10.     setTimeout(() => {: U9 c  k% Z( S( X+ p/ f& E
  11.       resolve(2);
    * C" X  j& A. P/ D( ]
  12.     }, 600);: ~( [( i5 _! u
  13.   });
    8 a' n$ G3 ~& H9 D3 O$ K
  14. }
    ; }% }0 z# }2 j" _2 K! s& V. Q& \
  15. const fn = () =>{
    . ]5 h& @) Y+ i) E5 V# Y
  16.    fn1().then(res1 =>{8 F" [6 @4 F$ @3 L6 [! r" ?3 \
  17.       console.log(res1);// 19 W8 P  c- I" m3 j
  18.       fn2().then(res2 =>{# F( C1 W' k6 m
  19.         console.log(res2)6 Z* s) l0 k! _  }2 C* g2 \$ U
  20.       })
    $ {! T& E; j7 j: F, a9 b4 e7 P4 G0 K
  21.    })/ V$ E5 N- p9 O6 X$ A) G1 v
  22. }
复制代码

& _9 Q9 i( r% G7 z' j1 K3 C1 y6 p吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进+ k/ Q" [8 O- a4 k) e- J6 b  }
  1. const fn = async () =>{
    + J" M$ H) {: [! t4 A. a
  2.   const res1 = await fn1();+ _' S' ?- x. S& V5 S
  3.   const res2 = await fn2();% B# E+ p* I& \/ i9 S2 J" Y  T
  4.   console.log(res1);// 1
      Z/ @2 C2 J4 D8 I9 g: t# K
  5.   console.log(res2);// 2
      j. R' l+ j# P) r( s) @
  6. }
复制代码

9 E) S: M, B6 x补充但是要做并发请求时,还是要用到# K: N4 I% ]0 S4 Y/ V0 w
  1. Promise.all()4 m: l, e0 o9 C7 T4 C
  2. const fn = () =>{
    9 u+ d. i$ Z& I+ l  y0 e; B- Q
  3.    Promise.all([fn1(),fn2()]).then(res =>{
    $ |" q/ x( h0 P/ X4 ^
  4.        console.log(res);// [1,2]
    1 }  G- }- A: T* }3 E
  5.    })
    $ f# c4 N( Z# S0 |
  6. }
复制代码
* C: X' T- i+ y9 N7 e
如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
0 \8 A2 k5 {0 I十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。
4 |7 v; U7 ^% r% N" {  U, K0 V# L8 s$ w+ s% A9 ]: E3 L

7 K; R/ a, R& S9 k- ^( e8 O+ x6 ~
# ~: L5 a/ l# ]1 H  x/ Z- A; A4 p9 D
中国领先的数字技术资源交流中心!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

5

主题

4

回帖

199

积分

学徒

积分
199
学费
176