漫潮者,私有云,NAS,新媒体电商.软件开发,商乾
标题:
你会用ES6,那倒是用啊!!!
[打印本页]
作者:
商乾美工
时间:
2022-4-29 17:32
标题:
你会用ES6,那倒是用啊!!!
(, 下载次数: 988)
上传
点击文件名下载附件
* v8 u& A% R2 I
不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
const obj = {
5 Z2 X6 R* q5 t3 N( C# x5 D
a:1,
- R. m5 D+ [* H' M G/ N8 f
b:2,
$ y, F; S+ s7 O9 w% N* g; N
c:3,
) W0 K6 r$ @ c9 m0 M" [( U# [# P
d:4,
/ ]/ p6 N0 {! A0 q2 i
e:5,
* B* J# L9 j* ~- u% d
}
复制代码
! a# r" d1 [* A& o% v- Q/ i+ E& C
吐槽:
8 \* t. H$ O: F# { S/ y7 X
const a = obj.a;
4 V3 w& n4 V8 _$ Z9 |/ ~& s
const b = obj.b;
' X, z; a F2 `- g2 t) }2 S& i
const c = obj.c;
5 ~5 ]! V+ @7 W
const d = obj.d;
, { q9 \; m. Z. F* G1 D" `- P5 S
const e = obj.e;
复制代码
6 X1 s* y2 _4 Q$ z
N9 _" K+ E! ~& }! M' c2 i
或者
: |: d6 p8 Y; O) a; i0 _, H4 q
const f = obj.a + obj.d;
; p! R5 ^8 h8 L1 N% K- U# e# W
const g = obj.c + obj.e;
复制代码
/ R9 O. ?$ ~% _
吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.
$ e- a; ?# J* k* O5 G
”改进:
( q7 z6 u' @/ u
const {a,b,c,d,e} = obj;
6 L0 z3 L) _* t& u9 s$ U- x, W# E
const f = a + d;
' l# N- h( Y' d5 ]5 s5 N$ U
const g = c + e;
复制代码
3 G+ U/ n. i. M+ k: B
反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:
" z2 J" R; i) k8 L: {; N$ l( F
const {a:a1} = obj;
6 i2 t- s+ N4 H% @
console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
4 ]' ^* B1 ~! t9 t2 g: @
const {a,b,c,d,e} = obj || {};
复制代码
- q+ g9 s3 k0 A& b- ?9 a4 d$ w E
二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];
9 w5 y- n2 d X$ P, t; r4 Z
const b = [1,5,6];
1 Z7 J4 w2 b- o% z0 U/ f* P) C
const c = a.concat(b);//[1,2,3,1,5,6]
: R t0 m& W' w' r7 x0 P! L
const obj1 = {
# _" `, [# u) b3 B* n: l
a:1,
; e4 l. t7 t' V
}
, w1 U7 U' Q, G# O; m9 l
const obj2 = {
$ x$ m* ^6 o) G1 _4 B) L) ~
b:1,
8 o* k7 |' M6 E6 ^3 h6 ]
}
* G3 f7 R/ c G# d ^5 N! I7 u
const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];
5 _% X. X% j3 r/ {
const b = [1,5,6];
g( l" @7 I2 l& l) |' T$ F
const c = [...new Set([...a,...b])];//[1,2,3,5,6]
c9 p7 y( V* y) [
const obj1 = {
1 Q- l0 t4 k1 t
a:1,
) P+ j* p. P- U* V. B2 Y! A) P
}
3 q, a4 E+ h. a9 }) K
const obj2 = {
8 X- {% ~% B+ \. I3 |* h5 L# Z
b:1,
- w; e( H" Y7 ~, E, W8 i
}
- p/ k% {% F% [
const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
0 q! ?1 T9 ^7 T
三、关于拼接字符串的吐槽
# u5 k' n I9 i% n& g' k
const name = '小明';
+ G. Z% V7 r J* ]- Y1 O
const score = 59;
7 r M) d, N2 [: s. c8 t
let result = '';
5 x: I( m9 J8 p2 _ \* W
if(score > 60){
0 d$ K* _+ J' t6 N* o9 f s7 ]
result = `${name}的考试成绩及格`;
, Y" h9 S" h5 r) X$ ^) T1 k
}else{
; H5 ^6 e' {1 h, J. _# K
result = `${name}的考试成绩不及格`;
7 C( O7 w x9 t5 G6 C6 w' F
}
复制代码
6 l: R& h/ n2 H
+ b, T/ x' F$ V9 X
吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';
4 y' n" R Y) l; S
const score = 59;
% A! Z1 {& ?5 @; b; |) m1 \* `
const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码
# x. r! \1 w: D$ H6 O2 ]) d8 W* c, E; Y
四、关于if中判断条件的吐槽if(
+ @' u% R0 G6 e$ ]; d. `' p
type == 1 ||
- Q5 n4 {( y7 R6 z- ?
type == 2 ||
3 g0 `1 k/ I8 X6 o3 B
type == 3 ||
6 [- X; S0 X2 B8 q
type == 4 ||
+ e3 [- ^2 ?8 D! O" C
){
# @) i' [/ l" a2 @
//...
% A: k! ~ k* w2 [' b1 e
}
复制代码
7 O0 r5 Z4 l( n
吐槽ES6中数组实例方法includes会不会使用呢?
' ^% G! D; G/ I( Q, U
改进const condition = [1,2,3,4];
) b+ {# F6 n" o* q/ b7 u W; [
if( condition.includes(type) ){
9 d# J) t, m* m8 A/ {( C. [
//...
: o8 W8 ~- Y d6 W
}
复制代码
$ s8 L( W3 R6 J& m
五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
5 A* j8 x+ r7 l9 n. O. n4 D
const result = a.filter(
2 G0 e% ?) I+ P0 @, }" r
item =>{
2 G2 t# }; @. t. N
return item === 3
% N1 [3 x2 C* E) z7 X/ X
}
. Q( V2 H* I* W3 S( ]
)
复制代码
" M3 w* f6 B0 U' y1 \% L& \& z
吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];
- K) e0 v2 l$ D; T. r9 _8 Z
const result = a.find(
. M# W/ d0 G, T, r, p
item =>{
1 j4 d& ^, W: R0 z- h; i$ @' X, J
return item === 3
9 h$ @& j) x; g* h
}
" ~& z" j5 ]+ O: J; T- h% w
)
复制代码
0 w, w6 b) O/ Q
% D5 x1 M2 ]9 G! _. X. w: O8 o+ X
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。
/ g. G8 I% k+ [7 S
const deps = {
* I& H! p+ }7 ^+ i
'采购部':[1,2,3],
; t* N' r$ U, I% G' o/ K
'人事部':[5,8,12],
! q& g1 t" t' w# s) g! [$ k2 O1 w
'行政部':[5,14,79],
! C! ]7 D1 M: b, u/ p5 }& I. c
'运输部':[3,64,105],
7 R# j1 T/ b- K2 w3 h7 u
}
% t8 ^, o! g6 y$ e1 \
let member = [];
1 b- t5 J$ g- K
for (let item in deps){
; U5 L& ]; `) G' S j3 v* m
const value = deps[item];
# n8 y# ^. p" _& P" l
if(Array.isArray(value)){
- ^1 w+ @/ q7 w* v( T
member = [...member,...value]
0 h- y( \' l( I* M
}
7 q: H |/ M f& M" H5 j
}
. z8 P3 t/ H. M Z* g6 ^
member = [...new Set(member)]
复制代码
1 ?. V1 L" _. G
4 }" F* Q7 _7 |4 U% a% B
吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
9 k% S- i+ B. Y9 d7 d3 D0 y
改进
O' u: e3 ^8 Q4 A7 j c4 }
const deps = {
+ H* K) G/ S7 x
'采购部':[1,2,3],
- E6 `; j0 E! \& E+ b
'人事部':[5,8,12],
! @/ e. H) V9 k
'行政部':[5,14,79],
3 l$ |* A# Y2 T, X. I6 ?% Z, T' G7 \
'运输部':[3,64,105],
" X+ o/ j1 _8 ~- L0 j7 w3 c
}
+ a! \8 z: L3 { ]' U2 }2 d1 c
let member = Object.values(deps).flat(Infinity);
复制代码
- c* j* g) U! n/ I, G
其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
8 `5 `6 Z! ~3 r% X* R
let index = 1;
% X5 ^2 ]% ]8 V# y9 ^$ b+ a* X
let key = `topic${index}`;
/ B5 t. c9 H7 a# v, }3 s( K+ S
obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};
+ k3 H) o. o" @2 r4 A
let index = 1;
1 k2 u! Y, g: k3 k E2 Y; S
obj[`topic${index}`] = '话题内容';
复制代码
2 s9 A' [4 m9 [& T" l" `& u; y# d( U
" k1 z% D9 t, B
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
6 d2 F/ B# I% [" ^2 A% c
//...
8 l' i l! n! V- g$ ]. E* b3 E
}
- _8 t! a' O- ^) r V
吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
' y* m" T+ ~# _; Q9 a$ A, t
if((value??'') !== ''){
! q$ A* l8 l# v- f
//...
& q0 q. [' a+ _* W' V
}
1 O# i! ]% w6 s
十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。
& j5 D S6 Z+ a* Q3 t
const fn1 = () =>{
: s* J+ ^' S1 _6 l$ ]
return new Promise((resolve, reject) => {
+ \9 z- i3 Q- ]
setTimeout(() => {
- {2 x$ p) N; u5 f( [
resolve(1);
4 r1 J6 L1 v, J% k
}, 300);
/ X& Q+ w2 @8 Z
});
2 T5 [, }. w4 Y0 N2 L& f
}
x6 k; x! `* d0 `0 l1 E
const fn2 = () =>{
F2 _. Z! H* W/ _2 I# ~
return new Promise((resolve, reject) => {
, d; V0 J M$ }5 x) s( L! s8 j
setTimeout(() => {
/ B+ M5 I1 k/ `' I- w5 O
resolve(2);
6 S. W. b9 W! X2 q1 M! \0 h
}, 600);
" g) w& t, p* u, i0 ?
});
7 C0 @; x$ X' |7 |( z, \2 t8 k
}
$ o2 T3 K$ f9 K5 P/ m! a
const fn = () =>{
/ K+ X9 w2 r1 T; D$ J: J
fn1().then(res1 =>{
. Q$ m! W- k; {, [ p2 }
console.log(res1);// 1
P9 l: B/ a. a" P
fn2().then(res2 =>{
4 \% U- L$ ^$ p, d5 T: a: M5 t8 u& p
console.log(res2)
! n6 L' x4 z% F& x' Y( K% l
})
" g7 ?- n* K. x2 L6 R2 d
})
0 j" C/ c! o5 ]& u5 N: v
}
复制代码
5 B! i: |& _8 {5 s$ a
吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进
$ {0 _/ \7 p7 k* m5 _! w
const fn = async () =>{
1 z+ s% {5 d* R5 U* f
const res1 = await fn1();
+ a% c* n$ y7 C7 c. O4 l
const res2 = await fn2();
- m1 d- @0 t# v+ O0 a
console.log(res1);// 1
. B, \$ i8 Z9 W. V
console.log(res2);// 2
4 F" P4 Q# X( o% a0 K, s
}
复制代码
' z# k2 X Y7 `7 `& F5 q: r+ u7 A2 h
补充但是要做并发请求时,还是要用到
) B* R# l; S3 }
Promise.all()
" ~" \ H, U% g5 O% [4 K0 u1 j
const fn = () =>{
( ?$ { i, o9 g) A
Promise.all([fn1(),fn2()]).then(res =>{
) o1 D. X9 D' i( m
console.log(res);// [1,2]
% I/ y' q/ Y8 w5 q* n
})
7 c% X" ?: t3 ^! _: n
}
复制代码
. @) B+ z: W/ B M
如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
& f, y" h% W8 k) d _: x; D. x& c6 b
十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。
( l% o! i) n6 S/ c4 }. M( c! ~
$ B9 P: C% f; l' J U! g
# r6 `& Q% ] r5 [5 o# a
7 d c, Y- T0 D; S
欢迎光临 漫潮者,私有云,NAS,新媒体电商.软件开发,商乾 (https://www.aurrel.com/)
Powered by Discuz! X3.5