登录网站,浏览更多精彩内容
您需要 登录 才可以下载或查看,没有账号?加入我们
×
6 z+ G0 Q, x" E- F
不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。- const obj = {9 b$ O6 H6 ^" ~0 n. b" B) F
- a:1,
4 x2 Q, z+ n0 y3 f - b:2,) Y; l9 g% ~ p* d
- c:3,
f5 N- P0 Q2 @* u/ y1 m- \! b* q - d:4,, r. D8 {: k: y6 b
- e:5," Z. n0 j& I" K
- }
复制代码
+ @; u$ v* U* b吐槽:
& |* i$ z; g9 s! f- const a = obj.a;
% g3 n* P* y N. c/ y - const b = obj.b;" o4 B( f# g" U; K4 E% J7 x
- const c = obj.c;0 }6 J" f; H, r% F% \
- const d = obj.d;" ?: h$ A1 w) z6 u2 R9 s4 P! Z
- const e = obj.e;
复制代码
5 ?- g5 Q8 c0 N# ?! a" z( Q" Y- N t* e4 R
或者0 p8 j! N ~0 N$ E: ]4 Z3 K3 G
- const f = obj.a + obj.d;* Y/ }9 w) t& P4 n4 Y! B
- const g = obj.c + obj.e;
复制代码 3 z" Q. [0 @! B8 f6 h, b8 j: `
吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.
5 |& ?6 F' D5 n V. M; I”改进:- N% g" e" o* Q+ A1 d
- const {a,b,c,d,e} = obj;' K% e8 p, K X: G! X
- const f = a + d;
1 u' z- J/ f4 ?+ W# o2 f; h: L' @ - const g = c + e;
复制代码
; O6 c8 v, {! c1 @9 V% W: t反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:& I5 d5 Q: v/ Q. @; a6 [
- const {a:a1} = obj;' B* F2 X0 ]) z4 O/ H* g% `
- console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。: H$ K- b7 [ x, X2 y
- const {a,b,c,d,e} = obj || {};
复制代码
" b& d+ r# |% Y+ K+ r二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];
8 z$ |8 j- Z7 Y9 @8 N6 g, U- const b = [1,5,6];4 F% e4 A. f6 T$ E+ O
- const c = a.concat(b);//[1,2,3,1,5,6]3 c) F3 q1 U( j0 s/ H
- const obj1 = {
6 N2 T7 Y1 r7 T# K3 D - a:1,
8 ]/ s2 s& @/ d - }
$ ~& |$ @; |& k& I( W - const obj2 = {7 t+ ?" J( \$ k# `6 r4 a
- b:1,! F. V( {$ s! Y! u% l
- } Z' o) l# \$ s9 e! k1 m% w+ g8 a
- const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];& t+ y# l0 ~1 e; a
- const b = [1,5,6];
" Q. Y8 A1 O' V& A# J& v - const c = [...new Set([...a,...b])];//[1,2,3,5,6]
% p* {0 S: y0 ~1 I - const obj1 = {+ I8 ^# J" E& E$ e7 w+ N9 a R
- a:1,$ u$ M: c- {( x4 U3 e- M
- }) I( R. a( ^& B3 k# z
- const obj2 = {
. S) S7 M4 v0 M, E: K9 j - b:1,
7 g9 s' v% l- \9 X& K& ` - }
' n! g1 L/ X' T* h' w A0 D { - const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
* c1 A: b) N Q+ f; q; Z三、关于拼接字符串的吐槽
0 k9 M5 A! k* t r3 T1 A- const name = '小明';
( m+ e# J! {5 |! r! I - const score = 59;2 T* R' d9 [4 y1 X# P. b6 `
- let result = '';
9 Z4 Q7 g' L! }6 ~; C* l - if(score > 60){6 W$ N0 A* e8 j
- result = `${name}的考试成绩及格`; 6 a3 N" F/ L5 W' J
- }else{6 l) g0 f3 p$ \
- result = `${name}的考试成绩不及格`; - z) [* m* q" D2 Q: ~/ ~1 U6 }
- }
复制代码
, x/ i7 O+ f) h0 X
0 L# H' \: S! \$ e% @0 X吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';
1 [1 r1 w3 p7 `5 z$ L- const score = 59;
- y5 o+ x1 e8 Z- `( E8 @+ s - const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码 7 K/ _2 q$ }. t+ X1 p* |$ N! ^
四、关于if中判断条件的吐槽if(
& m" p; S- r5 f8 G4 {- type == 1 ||
# Z4 D6 s+ l# p: R# W- b" x) k c' S( M - type == 2 ||$ M f9 N) p' W* P, E
- type == 3 ||$ x5 g+ _+ `( Q: d
- type == 4 ||' }6 ?0 N7 X0 e: r- I
- ){
( x, [& N% m/ P7 Y6 }' d - //...# X8 i; V+ {6 A; R- s; x! m* Q8 W* B
- }
复制代码
: v# e# Y% w/ h: T( ~, |吐槽ES6中数组实例方法includes会不会使用呢?
4 x5 a! J6 |' ^改进const condition = [1,2,3,4];2 J% b2 m: B) a- G( u
- if( condition.includes(type) ){
2 h- Y' X& K% G - //...
& Y4 h r6 ?; r5 q. P - }
复制代码
9 p$ A3 h( }8 x4 _4 I7 M8 y五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];4 f0 G& K( {" m. b# q/ h& O
- const result = a.filter(
7 w- \8 X+ w8 C. K: u - item =>{
1 i4 ^$ ?7 ~! Y" L4 G1 N) _9 a1 _7 } - return item === 3
, g& W2 k- \- m' }* q4 ~% @ - }$ R1 Z0 _' t. p0 _1 l' P
- )
复制代码
# x% b4 f1 T8 o; N吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];
) p8 v3 b4 b+ D# o) g# a; q- const result = a.find( . S5 ?, y+ U: \! i3 { D& R
- item =>{
p& e+ W# U7 M% V8 J4 d - return item === 3% y4 c9 D3 f3 H4 e& Y" E
- }
) Z- ~0 o; W3 [: V: M/ H - )
复制代码 - q5 B0 _/ Q' ~( H* I8 j
2 E# B ?* t$ J L' X
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。, L5 R! J8 v0 M) t) J( o7 L
- const deps = {1 I L4 R0 e% a8 K+ P
- '采购部':[1,2,3],
1 F( \1 S& Q3 u, l, ^7 K( t - '人事部':[5,8,12],6 F; P6 x5 O6 a# \" x
- '行政部':[5,14,79],5 J; A+ v) l, W l- X1 t$ r
- '运输部':[3,64,105],0 `- T; \2 u% r' D
- }
* ~' l9 _% L& \1 w% R" t - let member = [];( q) Z7 u, n, l+ w
- for (let item in deps){
' {% x+ y3 _+ P. v - const value = deps[item];; ~6 v$ M8 n& m' J
- if(Array.isArray(value)){
, N) p* @) k5 U5 W9 h3 u' U- m% u - member = [...member,...value]
, i% U& q8 F0 u% l - }
6 X( `5 G0 L2 N - }/ H* z. W% s( u. Q P1 t
- member = [...new Set(member)]
复制代码 + W, u- C) t" o. x2 L
* N; s1 @/ p5 A
吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?5 V! x& Z/ {2 m' `$ f% N: v. v
改进3 N* o4 v( l9 {- Z5 J$ ~, m
- const deps = {( @8 O! [ s5 C# ]; [) E
- '采购部':[1,2,3],
' ~; z; x3 c+ y5 l/ U- _ - '人事部':[5,8,12],' `- b* \# b6 f D6 V3 c
- '行政部':[5,14,79],
* y1 h `( Z2 I% d# C - '运输部':[3,64,105],* J, n8 I# V" j2 [
- }8 h6 v6 S. e% d) U+ S2 W: M
- let member = Object.values(deps).flat(Infinity);
复制代码
2 m4 T d" _7 J4 J# o其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
6 z0 O2 D' k) s! G- let index = 1;
! H8 R2 Q* B1 q& w# ?8 x3 j4 _ - let key = `topic${index}`;
! L+ e+ a4 I, F) W5 N! d' A - obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};
% \6 A7 O) m% _; h1 O) ]2 s - let index = 1;2 X' S# }4 P9 b! ~2 m0 n
- obj[`topic${index}`] = '话题内容';
复制代码 1 C5 _9 `3 T2 z1 S+ f! @# O8 r
. |8 x1 e8 v( P, A
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
% l7 J4 C+ p! P! u, Q //...; _: u/ e/ \6 l# e
}
( m; m& o( E- |/ P& B9 w吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?4 [$ L# u, _- T9 ^5 @. Z7 j6 u2 E
if((value??'') !== ''){
2 @# y' r& e( Z' S7 A2 m1 L //...7 R7 Q3 `; u2 T8 J
}' T. ^% Y" U( H5 k7 a. w
十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。
- J/ g0 V9 k* \# X; J- const fn1 = () =>{
+ o4 n( h' ~! e, h3 v9 R - return new Promise((resolve, reject) => {
, I2 u" |! K* p t. Q: t& l) b7 u - setTimeout(() => {
% G( I$ {. v2 r* Z& ~) H - resolve(1); {) y4 L1 o d* ~
- }, 300);
4 {+ ]7 T; |; l4 e9 C3 l8 o5 \ - });4 u$ i7 V3 c" x {( l
- }+ a& t8 m6 {$ m) b1 R
- const fn2 = () =>{3 |- I9 E! C' C7 D7 O
- return new Promise((resolve, reject) => {
, ^( e, ]" L( O* U7 M - setTimeout(() => {7 e! v6 `) _' B3 K; x
- resolve(2);
; N3 x; _) ^7 x8 C - }, 600);
4 Q: q& k1 u# D+ I - });
" T, X$ d5 u) u - }
. a% n6 E+ s9 s2 } - const fn = () =>{ O( q. }. P$ `4 B# p: B
- fn1().then(res1 =>{" L* J( x0 N' l0 i/ [* N
- console.log(res1);// 1; n& t& ] g$ u
- fn2().then(res2 =>{
/ }4 t$ x) g; Z" G9 G' } - console.log(res2)7 _0 w' y9 L ?3 E6 R8 D
- })
5 p7 s6 _ z7 e4 U( G0 g4 z - })8 i: A1 E/ O- p! n0 ?# v
- }
复制代码 ' J4 L+ N( ?; k5 ]% G& t
吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进9 b e& y5 H1 }4 X& S) d5 k
- const fn = async () =>{" l- {: n% r( f- y$ P
- const res1 = await fn1();
* _: w: D5 ]; n; ]% d8 n) v2 _: n# J ? - const res2 = await fn2();
# r" ]9 m1 h6 X/ e5 z% l( g( v6 K - console.log(res1);// 1
8 C1 X+ L" m0 q1 s) }) F - console.log(res2);// 2
! F4 C) O8 g, d% B( l& H - }
复制代码
* f- `; i/ t! ~6 I, w% p补充但是要做并发请求时,还是要用到: Y9 ]9 L; G& x! Z T: }1 ?
- Promise.all()
, b- x0 U9 H2 A5 p$ ] - const fn = () =>{; O4 e* m( F y6 I5 h$ P9 t
- Promise.all([fn1(),fn2()]).then(res =>{1 N* |& L/ {- A- w0 A& N3 p
- console.log(res);// [1,2]
2 I! ^8 X* a4 E+ k3 S - }) ; }' M3 ^4 g+ k. T& b0 a
- }
复制代码
# \" r0 q: M; o0 ?7 M如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。) s8 P# I5 u6 @. O
十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。! ?9 m I3 X6 ?
. f c5 R+ N* p2 ?
) C1 g$ H F! K' M8 [( R6 G6 Y
* D( s* Q) w6 B1 v8 v6 E0 l: o4 b
|
|