请选择 进入手机版 | 继续访问电脑版
返回顶部
热门问答 更多热门问答
技术文章 更多技术文章

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

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

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

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

x
20220429_112551_043.jpg             3 i4 L0 H1 J6 Q6 ^  F
不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
  1. const obj = {
    ! d2 |) t% {( b% I& t: O
  2.     a:1,
    / z6 O: y# g: Y
  3.     b:2,! I# V% c" I3 Z4 v3 y+ Q
  4.     c:3,
    , V2 ~, [( [2 Z, W  y( Q
  5.     d:4,5 R8 }( H0 e1 b' V. \8 T" }
  6.     e:5,1 i9 {7 v8 S0 G3 Y6 z2 B! P
  7. }
复制代码
* Y4 e6 n4 b; i/ A9 U
吐槽:5 H' A+ J* W" b
  1. const a = obj.a;
    2 `9 r$ K. R0 c- Q! n* P% [+ q
  2. const b = obj.b;5 F  `: L  F' n- d- i% q
  3. const c = obj.c;
    $ j1 E7 L1 @2 `/ \. ?% |* P
  4. const d = obj.d;- W' _( F2 x' n9 u- p( @* a
  5. const e = obj.e;
复制代码

# n8 W: V1 {; ~4 F- ^; B6 d5 U& M' I& I7 {/ {2 i' w' N
或者
" [% r+ G$ F& \) c
  1. const f = obj.a + obj.d;
    + g4 A0 [: x/ j- n8 c+ _
  2. const g = obj.c + obj.e;
复制代码
4 P1 ^% j) j8 M7 I
吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.5 C* L9 v- ]4 `) l6 T
”改进:4 t( N1 ^- w1 Q  {
  1. const {a,b,c,d,e} = obj;& C0 H) e$ K* Z6 v7 c# b
  2. const f = a + d;
    - a% R( Y" `1 r, }  A. {6 x
  3. const g = c + e;
复制代码

$ D0 M$ m7 F# u$ M反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:
3 y. J+ D' E4 @, I
  1. const {a:a1} = obj;
    3 f$ d# C" t% M. U, i2 e
  2. console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。, T, O( M3 [, A8 o
  3. const {a,b,c,d,e} = obj || {};
复制代码
% n( m" n* G  j" F5 ^/ `4 }; v
二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];
" w# X' E- w- _4 H( p
  1. const b = [1,5,6];
    % U, L4 x7 y  R
  2. const c = a.concat(b);//[1,2,3,1,5,6]% p) U: E* y+ N6 N
  3. const obj1 = {
    4 L4 T1 G/ {( k# X# T) J
  4.   a:1,
    * R! |0 P$ x- |0 M9 I) s
  5. }
    6 q" {* A# ^5 n/ l3 p  I$ H
  6. const obj2 = {
    6 t  B* u5 M5 H* v+ q9 E! s
  7.   b:1,- Z5 Q* l& u; d- b, Z
  8. }) n* U8 E' d; a% r
  9. const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];
    3 |3 }; V% l+ E8 e
  10. const b = [1,5,6];  H5 H6 S8 W- `, Y. ]; R$ o4 y& f9 n6 c
  11. const c = [...new Set([...a,...b])];//[1,2,3,5,6]' O2 K5 |  J  B# s8 x( D( A
  12. const obj1 = {- y  Z0 i+ }" p, O
  13.   a:1,: y) {: M; q; f- o) \6 a$ v
  14. }
    $ g4 j4 g8 @* X1 |, P# \! G
  15. const obj2 = {. k# Z) H: d4 r) N* v* |. L
  16.   b:1,/ D3 X. z0 z3 E; _$ Y
  17. }
    " J4 c2 w, ?' V) h& E* s0 g
  18. const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
$ o  J8 {; g4 K- _$ X8 Y& C  T
三、关于拼接字符串的吐槽- P+ @: N$ N' V9 ~7 a
  1. const name = '小明';
    2 k. w5 }! Y' i: o# O4 [
  2. const score = 59;
    2 d, a) ~* v0 Q' w. ~$ R  k1 Z
  3. let result = '';
    3 p" ~; \- a  U5 s
  4. if(score > 60){
    6 K0 y4 r- P7 x, n
  5.   result = `${name}的考试成绩及格`;
    . ~, t4 x& q9 ~
  6. }else{; r0 E$ d& L- \$ x# i
  7.   result = `${name}的考试成绩不及格`;
    - }4 M2 n- W# J. U5 J
  8. }
复制代码
6 G# a1 ?- k: U$ P
' U( `! ~+ q' Y+ w: q3 \: {" ]
吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';
' b6 q8 z. {: F0 K8 g1 `9 y" }
  1. const score = 59;
      P2 x* I) m2 c  W& D
  2. const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码
/ t3 S( q: d+ ~/ T$ e
四、关于if中判断条件的吐槽if(, W4 x. s  W* L+ s2 F% m, W+ @
  1.     type == 1 ||
    0 u/ \- I' k# G8 Y
  2.     type == 2 ||/ o* D, ]! M9 \3 s7 \
  3.     type == 3 ||# v! n9 T5 v" F* u
  4.     type == 4 ||- |, P& R* d2 B: O- l0 U
  5. ){3 v2 `  B0 [5 U; k& {; F
  6.    //..., @/ Y, L  |, Y/ L
  7. }
复制代码
! j2 t2 n& x  o4 t4 i3 P% T
吐槽ES6中数组实例方法includes会不会使用呢?% o# X- u* u& i0 t" [) A% {8 f
改进const condition = [1,2,3,4];
: ^( d# v, v# `
  1. if( condition.includes(type) ){& H' Z8 R9 [( l! P* u3 ^! @
  2.    //...
    % F& x7 ]) R( V; j' t. q6 J
  3. }
复制代码
2 p- ?  b% i, u  A
五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
5 Q$ c( p1 \6 H' u/ I
  1. const result = a.filter( - U2 D8 z6 N2 B4 v" J) v$ O3 d
  2.   item =>{6 s* G) ~- B! E- D4 c
  3.     return item === 37 t  S- @- H) N$ |$ j
  4.   }( _+ H& [: K9 `# J3 Q! _
  5. )
复制代码

) c' G) G# p1 X: h* |吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];! e9 Q$ A* A. o+ A, G* ]7 E
  1. const result = a.find(
    2 H4 N1 @! f1 Z
  2.   item =>{
    2 e, _' {5 h$ L5 Q2 ]+ ~3 }
  3.     return item === 3
    " V, P! i+ J# V3 I
  4.   }- ^& C6 ^$ {! D) }/ o* y8 q9 t
  5. )
复制代码

; r% \/ o" }, U! k: ]8 U) x/ c: d& y0 `3 M( w: ]
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。( f- a* G+ L7 k; A: d7 k
  1. const deps = {* u4 e7 b# s1 ^' X0 v; Q. i6 ]
  2. '采购部':[1,2,3],
    ( K* t+ v0 @4 l* ~3 ^- R
  3. '人事部':[5,8,12],
    9 X2 G# Y3 d! o5 H+ X0 h  g
  4. '行政部':[5,14,79],
    0 x% ~6 C7 R7 z$ h8 u2 h+ C
  5. '运输部':[3,64,105],
    0 v$ F: {4 M3 g. Y1 f
  6. }
    8 X. o, {+ D% D' \6 w! ^) v" _: F2 Q
  7. let member = [];
    ! u- Q& \/ C9 A" ~2 _0 W
  8. for (let item in deps){$ H9 ^& o* T# \# o. [
  9.     const value = deps[item];
    5 |3 |' X5 C* {
  10.     if(Array.isArray(value)){
    $ ]* m5 H) m' s; C; j  r/ `7 p
  11.         member = [...member,...value]
    9 G  c) ~! Z0 L; Y
  12.     }
    # S2 ^/ j7 }4 ^& s) J; a
  13. }
    " Y" n$ ^" i6 q* W( F
  14. member = [...new Set(member)]
复制代码

! M# x% `; z+ q: K: V5 y
6 W  M* H7 K) h0 F5 Z吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
8 G4 a4 J: s6 i/ W$ a改进+ t/ K: C, j" [5 j
  1. const deps = {) \& X$ @2 f" L# f6 J6 P
  2.     '采购部':[1,2,3],% H1 W1 r2 m* |  Z' D. R
  3.     '人事部':[5,8,12],! M2 W5 q3 A1 \5 U1 V1 n7 p9 g
  4.     '行政部':[5,14,79],
    * C( x. m( Z! r: l) I) Z  f
  5.     '运输部':[3,64,105],/ a* W* T# s$ [7 W8 V. U9 N
  6. }" y; s8 R0 G1 R
  7. let member = Object.values(deps).flat(Infinity);
复制代码

: Q2 [- Y! c7 {- k& e其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
6 K& [% @' y- C  G! m! M& c
  1. let index = 1;
    2 ]. U  V6 y) _7 `3 W
  2. let key = `topic${index}`;
    & ~& |$ x8 H; z+ x$ {  h1 U
  3. obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};8 e3 i! n  R# G
  4. let index = 1;/ H& s/ L+ \$ X. f) U5 C
  5. obj[`topic${index}`] = '话题内容';
复制代码
+ J+ v8 I: B" M" I" J5 w
3 Q5 l% |. U$ T5 g: ?( ]
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
% n  y+ C* i. y& x    //...- o; U8 B1 S/ o8 J( v1 b' Q
}
$ |9 S* N  P: P) ]9 e5 W吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
* o/ Y$ }6 W# K' F7 m+ f7 v5 D: gif((value??'') !== ''){1 j" Q- n4 _( W5 ?$ U! j7 {) E
  //...1 Z* n3 E3 O) c% S% X
}
1 @4 D. r. u7 `- L! C7 Q十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。
: R3 F* c8 B0 L
  1. const fn1 = () =>{
    ! T, j+ D* J" p" J; t
  2.   return new Promise((resolve, reject) => {9 p' F' o1 h  f- Y! u% p
  3.     setTimeout(() => {
    / ?* J$ r) w, G2 h+ `1 t+ M
  4.       resolve(1);
      U% H# ]+ {; y) S, |9 \
  5.     }, 300);
    + d; _! d5 I& F6 j0 @
  6.   });
    ( }0 V+ b) d& s7 ]/ f3 R' j' V* u- ]2 @
  7. }
    1 J, N! Q0 v5 X9 `' P6 {+ F
  8. const fn2 = () =>{
    ) a$ O/ O1 C, c& L5 X3 s
  9.   return new Promise((resolve, reject) => {
    ! I  c5 ]3 H" b0 H# p9 W  c
  10.     setTimeout(() => {
    3 ~" v) o& y/ l" j6 e. s6 F
  11.       resolve(2);
    ! F9 H3 l% C3 h, U0 `, x8 u* p; G2 s  S: C
  12.     }, 600);) b, y8 l8 J  r0 I. e6 {; ^6 h
  13.   });
    2 s  c* O+ J2 A( N
  14. }5 E( f: O) }3 z- k" W
  15. const fn = () =>{1 [# S1 {1 {9 x0 C+ k  u  `
  16.    fn1().then(res1 =>{. s/ C% o, x2 x: A0 I( B2 {$ ?: f
  17.       console.log(res1);// 1: \  A; z# ]& }! @6 M4 H9 J5 E) h) n
  18.       fn2().then(res2 =>{8 ?8 ]6 l* Z5 \& }8 X
  19.         console.log(res2)
    : S; g- ~# N, H
  20.       })1 ~; G5 q3 ?: T# b& M5 Q5 Z
  21.    }), m3 A8 ~$ A# I* O: s7 k
  22. }
复制代码

7 m* y4 h( T( F. w3 g9 g+ x吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进9 g6 ]' q  N% }
  1. const fn = async () =>{
    ' O# I" s2 v2 ^) N0 s
  2.   const res1 = await fn1();
    " U+ z7 m- x+ [5 h% X1 ]4 {$ }" i
  3.   const res2 = await fn2();& v) C8 d8 }& N6 c/ q2 I7 E6 `
  4.   console.log(res1);// 10 q& G( g; ]# W5 z
  5.   console.log(res2);// 2( f5 L3 m7 T" k% u
  6. }
复制代码

4 N1 P/ v  M! ^/ E% H) ?8 E* [补充但是要做并发请求时,还是要用到$ w6 X& d- Q3 U- J. S
  1. Promise.all()
    + M5 H1 c: C) w9 V1 E$ u# l8 R
  2. const fn = () =>{# |: v- h) D" b' e6 L
  3.    Promise.all([fn1(),fn2()]).then(res =>{; }! B( S) @1 g* i3 V6 P& l, z* m* A
  4.        console.log(res);// [1,2]. `  B5 V: B0 Y  `+ @% y9 w# w1 q: h# i
  5.    })
    " k+ D" Z& F2 H, I
  6. }
复制代码
3 S: |$ x) q) I
如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
4 E, L/ S, Q  P0 W& e  f十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。# K4 s3 b% b6 [1 Z; _2 |
6 J! F3 f2 h# d0 w) d

7 v4 W% y( a, l2 n; p8 h$ P3 t( Q/ f- q1 a$ G' ~' {) j
做电商找商乾,中国最大的电商技术资源交流中心!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

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

  • 微信公众号

  • 商务合作