返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

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

[复制链接]
商乾美工 显示全部楼层 发表于 2022-4-29 17:32:45 |阅读模式 打印 上一主题 下一主题

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

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

x
20220429_112551_043.jpg             
6 A/ L# F& c: h7 `8 @+ d8 s; j, i; u不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
  1. const obj = {: {8 F( X% g! D. @5 B! n
  2.     a:1,
    ' a/ b, Y" y9 j0 W2 J: h
  3.     b:2,7 R, C: f( j& Y& j) q/ Y
  4.     c:3,( ?6 V) U) q. U- Q
  5.     d:4,7 ?$ P* m8 C1 ?* F% Y+ F# Q8 E/ r' E
  6.     e:5,
      M/ Y* i4 i. s0 u  p& }% ^
  7. }
复制代码
$ y9 n  D1 x( q
吐槽:" W' t6 |& \( b6 J/ ~1 y/ f  g; }
  1. const a = obj.a;% c( b3 d8 }! p2 d* R
  2. const b = obj.b;
    . V  w" D  b) U8 Q
  3. const c = obj.c;- j1 }: t9 a5 H
  4. const d = obj.d;
    * a( E9 C! x6 V
  5. const e = obj.e;
复制代码
8 m: C8 H8 Y2 S
3 m+ q. b6 `( I0 A8 [
或者9 q* ~7 g2 m% |# J" u' E
  1. const f = obj.a + obj.d;
    4 s, S3 N: d! a" z  @
  2. const g = obj.c + obj.e;
复制代码
( |/ v# p/ n# `0 Z4 F
吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.
) ~, L) `- S  a3 F. J, C* }”改进:" ?6 u$ m7 l+ K
  1. const {a,b,c,d,e} = obj;
    # Q+ h. ^0 r5 |2 q$ p
  2. const f = a + d;
    7 W- x- y$ J6 l6 p6 M
  3. const g = c + e;
复制代码

( v) V) u3 F1 t反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:
- b% W0 V0 b+ W  i. y# ]! K. [% b
  1. const {a:a1} = obj;
    : r" H  s4 ^1 T' f9 F% a; ^
  2. console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。5 \+ Z  k( M( K1 f& _
  3. const {a,b,c,d,e} = obj || {};
复制代码
/ q% N( b; v  C/ A" P
二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];, u3 W* ?' H4 f- _+ E
  1. const b = [1,5,6];
    , X  ~; ^6 S2 m; @0 d/ Z
  2. const c = a.concat(b);//[1,2,3,1,5,6]
    9 d* H+ H8 g- N  ?+ w  q$ m2 q
  3. const obj1 = {+ ?1 i5 W0 T' X8 B4 S  j; a
  4.   a:1,8 P$ U2 V2 [* J6 L; O
  5. }' E+ G- z' I! Y3 X
  6. const obj2 = {
    1 U: T7 @5 U6 x; x) s$ |
  7.   b:1,8 @" l& g0 m5 @  `0 I; ^" [
  8. }
    $ p4 l8 i& `( r% O7 g* g* C  ]  B
  9. const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];- `+ a7 T/ g. y' r2 Y/ u
  10. const b = [1,5,6];
    / |3 q+ ~/ s4 }, ]3 F! c
  11. const c = [...new Set([...a,...b])];//[1,2,3,5,6]
    # {5 {3 ]! T$ B9 W2 S
  12. const obj1 = {
    ; Z" J$ Q/ G7 v9 H; P# e
  13.   a:1,4 h* t4 D; l2 ~: F2 Z
  14. }; O  H8 F2 M2 [0 m9 o0 L
  15. const obj2 = {# X  q; L7 M) u* I' k8 W
  16.   b:1,0 g: L9 m8 h: [/ g$ M( G' c
  17. }4 }; n# {  ^+ _  @! w' V- j
  18. const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
' w' a1 t1 n" j8 O1 h
三、关于拼接字符串的吐槽
( X/ g4 t' }6 C" y& G
  1. const name = '小明';
    ; ^8 @1 a+ U. g! H' K
  2. const score = 59;
    , T; x) O5 P# v% c% ]
  3. let result = '';) P  h- w7 w. g+ t' R" S3 }
  4. if(score > 60){0 u' @; W* U  T$ c
  5.   result = `${name}的考试成绩及格`;
      s8 E4 K, y/ S
  6. }else{) B- X) n, l% I( ]* r' ~
  7.   result = `${name}的考试成绩不及格`; - |6 v" C& \( @8 {
  8. }
复制代码

2 c/ Q" f" o( B
4 K! m2 c, T% U0 ^4 W+ b吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';7 o  n1 |4 k' j
  1. const score = 59;
      m- C' r  y5 n) k
  2. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码
3 c; y! x' J) U: V
四、关于if中判断条件的吐槽if(* [7 V5 F' L) v% M" e
  1.     type == 1 ||
    - h9 {8 l. g4 {- |$ [
  2.     type == 2 ||& ]9 U4 n- s+ [& f0 q  `; T
  3.     type == 3 ||( B6 n  r. r1 y8 T  k; [5 c  a
  4.     type == 4 ||$ e" O% f" k: I6 o4 S
  5. ){
    2 N7 Q. t) s$ [, x3 n- ^/ k
  6.    //..." ]4 S' O7 _, I: t& Z" V
  7. }
复制代码

. U' |+ h- @. z吐槽ES6中数组实例方法includes会不会使用呢?9 H6 H5 F/ P& |. U6 I
改进const condition = [1,2,3,4];' i) O' I5 `+ b; X: m( G( Q6 ?( k
  1. if( condition.includes(type) ){* m! a$ t) ^) K8 V, i5 ~2 x9 `& F
  2.    //...
    * m  M4 z2 ~: J( f# t( x: r
  3. }
复制代码
. q* b2 b6 s  p; W
五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
9 Y. A1 C) B$ o3 W5 K
  1. const result = a.filter(   O7 j- N+ A! H5 a) l" c
  2.   item =>{7 Y3 i4 K6 d/ ~" G( j/ Y4 u
  3.     return item === 3
    ; i2 O* x9 v3 X- a3 u' p2 v* k
  4.   }7 B7 R# O1 E4 V$ I
  5. )
复制代码
* F) M' y, Z4 U" T8 w: F9 c
吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];- s) U1 ?5 Q, L. Z3 c4 Q
  1. const result = a.find( - r, J4 b8 |! w; m2 u$ x$ I) s2 G
  2.   item =>{
    + I$ g9 @$ E5 W+ e# S. M
  3.     return item === 3) n! s. G) G8 q4 q; R; e$ @
  4.   }1 _2 G4 j+ X+ X( @% j' V
  5. )
复制代码

$ U. Y  F, i  [2 U( {- S* h" x% C( Q1 x7 y
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。1 w" C( H, y, _, E8 P  y
  1. const deps = {
    8 H* ]3 D3 q0 i& u' |9 I. E
  2. '采购部':[1,2,3],* G) Y: \# m9 z9 z8 j6 k; |
  3. '人事部':[5,8,12],: E- z4 E( R7 c7 E
  4. '行政部':[5,14,79],
      Z. N9 h' P$ C7 r3 Y( b
  5. '运输部':[3,64,105],) ~; f4 W3 G( n5 D
  6. }, D; q7 R" b8 g
  7. let member = [];# M5 X* u6 o0 c; R% C
  8. for (let item in deps){
    7 v& Y4 y* G# s
  9.     const value = deps[item];: E' f+ v: F! {" m# P
  10.     if(Array.isArray(value)){
    , J+ O' f; U% c" Z
  11.         member = [...member,...value]& }" S" w* [  `3 u+ H# z. ^
  12.     }- L8 Z- g, v/ _/ A- e0 l1 J2 N- h
  13. }/ h/ C% q7 A4 C& O8 U  B, E
  14. member = [...new Set(member)]
复制代码
( k$ \3 R- `, G/ C* k  j

- S# d& B/ F* |吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
3 \2 m7 @3 ]2 P5 M0 z改进" X1 p, I8 E$ W8 \
  1. const deps = {
    7 F: Y" ~9 Z1 b
  2.     '采购部':[1,2,3],& l- M% A& A$ t, z% l" _+ \& c
  3.     '人事部':[5,8,12],
    8 \% E/ Q  O4 L& R
  4.     '行政部':[5,14,79],
    0 u0 m1 x  ~0 _7 E% s& E  J# r  b
  5.     '运输部':[3,64,105],3 x* S$ Y# X1 n& v
  6. }; H+ B% F: @8 N& O+ A% G' ]
  7. let member = Object.values(deps).flat(Infinity);
复制代码
0 _5 |8 S/ w' v/ \9 P9 P3 t
其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};+ X2 T9 }& @/ Z$ }' X
  1. let index = 1;$ L2 x7 o& L) V+ O' u0 R
  2. let key = `topic${index}`;
    8 E$ R3 e3 [  d) K/ Y2 _, f5 S( F
  3. obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};, V% {4 w8 _0 o% A1 X* x) Q1 Y& }& e
  4. let index = 1;) `; M, `8 a5 J
  5. obj[`topic${index}`] = '话题内容';
复制代码
+ Z" T; s3 A2 h6 Z3 \2 j
- d8 D+ f' V7 K' n# g2 S5 m
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
) S8 T  P: q& o& x    //...9 w7 _8 r9 W0 z1 q3 Y0 \& r. Q
}
6 G' z. F$ K& F. V吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
: q2 S' V+ E9 O% F, uif((value??'') !== ''){
0 E4 R2 y) c6 O7 T  //...
% ^$ `. r6 m% O  g8 ]7 N( l}
+ @  j# J9 ?4 ]# g3 N十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。. _9 u9 _, o) Q0 R2 f- u& S- _" Z
  1. const fn1 = () =>{
    * b9 \- O% J$ k  U
  2.   return new Promise((resolve, reject) => {
    * \( U6 A' ^& l2 }9 D
  3.     setTimeout(() => {
    5 u. N8 R) Y  f+ E' S/ b
  4.       resolve(1);8 U2 k7 L+ l0 i, B- [( c8 x
  5.     }, 300);
    " M/ R6 M. s% L5 c, \
  6.   });- c, Z. z- o4 e1 s1 _/ X9 T
  7. }+ X$ Z* d& D/ ~, r( K2 {( U1 W% ]! ~5 R
  8. const fn2 = () =>{6 ^; R0 H* f0 ?/ ]7 u: t0 G" Y
  9.   return new Promise((resolve, reject) => {
    ( g3 I$ r* }, ~! b( {
  10.     setTimeout(() => {
    $ H" T1 G9 q  D% m; o- [
  11.       resolve(2);
    ! x6 ]2 s. z# W: b2 h8 U- |) P
  12.     }, 600);& V  D0 Q- [# G& n
  13.   });
    ! m1 r5 _! k* i
  14. }
    ( N* n8 t* ~. `1 P
  15. const fn = () =>{2 n% d* @) p# k: F/ O9 M& M# p# Q2 }  [
  16.    fn1().then(res1 =>{# p5 |/ [* M- @8 Z8 k
  17.       console.log(res1);// 1
    $ O0 B4 j& L# w+ T! o7 L3 F  Q! e( M: w3 ]
  18.       fn2().then(res2 =>{: k; l8 C) `( H. X) l+ w8 A& Q
  19.         console.log(res2)
    9 x- J$ m' Y* |. i4 ^& u
  20.       })
    9 l* D/ J6 b' ^! Z' G1 f& j
  21.    })
    . R) r: b. W8 W2 Q5 Z9 r$ w1 l
  22. }
复制代码
& h6 h+ S* @( s! w( z9 X7 f
吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进1 q; s; d0 ]% U) j- _
  1. const fn = async () =>{
    3 j& E# R, ?0 v- j- w2 k
  2.   const res1 = await fn1();% e% Z9 Y. t* K; x' y  Y' w4 ~3 W
  3.   const res2 = await fn2();& |' T0 T! P& ?9 [- a# [9 n
  4.   console.log(res1);// 1
    1 m- r- [+ q, Q7 g) T* d
  5.   console.log(res2);// 2
    ; A+ P, S4 f$ |! I- U% w! j
  6. }
复制代码
5 O4 D7 }$ Q3 m
补充但是要做并发请求时,还是要用到6 H: B# \) ~: P6 m2 a8 T
  1. Promise.all()# o! o/ Y; o- f7 X  c
  2. const fn = () =>{! W) x$ m8 O* A  R* h8 b
  3.    Promise.all([fn1(),fn2()]).then(res =>{
    ! d& z, A3 F9 v
  4.        console.log(res);// [1,2]7 _, Q5 \1 g4 x: _8 a
  5.    }) 8 K% ~- n$ G# ?2 F+ \. A
  6. }
复制代码

3 A8 e. y) Q0 G4 C' r% p# T如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。$ A+ |+ |+ V0 n) b! f2 a$ t
十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。, |2 X6 i3 g1 C! z& T
: I  m: f  i3 P* F# z
( k. p: Z% s& M
2 ]' M+ o9 X% t( `* \
中国领先的数字技术资源交流中心!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

商乾全球电商人、电商交流学习与电商实战技术分享、电商爬虫、生活交流专业网站
  • 官方手机版

  • 微信公众号

  • 商务合作