漫潮者,私有云,NAS,新媒体电商.软件开发,商乾
标题:
你会用ES6,那倒是用啊!!!
[打印本页]
作者:
商乾美工
时间:
2022-4-29 17:32
标题:
你会用ES6,那倒是用啊!!!
(, 下载次数: 13)
上传
点击文件名下载附件
0 F' x3 E9 b/ U$ r5 V% f
不是标题党,这是一位leader在一次代码评审会对小组成员发出的“怒吼”,原因是在代码评审中发现很多地方还是采用ES5的写法,也不是说用ES5写法不行,会有BUG,只是造成代码量增多,可读性变差而已。恰好,这位leader有代码洁癖,面对3~5年经验的成员,还写这种水平的代码,极为不满,不断对代码进行吐槽。不过对于他的吐槽,我感觉还是有很大收获的,故就把leader的吐槽记录下来,分享给掘友们,觉得有收获点个赞,有错误的或者更好的写法,非常欢迎在评论中留言。ps:ES5之后的JS语法统称ES6!!!一、关于取值的吐槽取值在程序中非常常见,比如从对象obj中取值。
const obj = {
% Z% s! Z9 `' @/ N7 Y8 b
a:1,
. X6 Q% k! h Y2 Z9 t- b
b:2,
, K1 A) g) Y9 Z) n
c:3,
) Z# V- P: t" E$ ~- F3 n0 {
d:4,
' o. q6 o" G3 Z; t0 R6 L
e:5,
J& \9 p. b5 T0 p6 X4 ^) R
}
复制代码
( z' ? z' P8 k+ i$ ^ g
吐槽:
" L6 V* C5 {" r. S# Q+ U- U
const a = obj.a;
/ H3 U6 _$ E. Q( d* M' ]1 @% E
const b = obj.b;
]7 C* Z h$ n: |( Y+ Z+ C) A
const c = obj.c;
6 \. e5 F# c c% x7 ^1 H
const d = obj.d;
6 i& W" H: i+ o" U* S3 ~; C* f- b
const e = obj.e;
复制代码
9 H; X7 x; n# d- s2 l
2 M& s- ?$ \- \. O
或者
+ _% y: s% W6 [$ h7 S1 G
const f = obj.a + obj.d;
2 e7 q8 u: |3 S4 C9 R
const g = obj.c + obj.e;
复制代码
/ m2 W! V% ^4 y- J/ p6 \
吐槽:“不会用ES6的解构赋值来取值吗?5行代码用1行代码搞定不香吗?直接用对象名加属性名去取值,要是对象名短还好,很长呢?搞得代码中到处都是这个对象名.
* w9 w& f; c6 K' Y
”改进:
; c2 _3 k) d3 @% f
const {a,b,c,d,e} = obj;
& z- T* V6 i+ K, H1 @
const f = a + d;
- ^$ ^% P" Q& o5 j
const g = c + e;
复制代码
( o* f/ t; J3 n: g
反驳不是不用ES6的解构赋值,而是服务端返回的数据对象中的属性名不是我想要的,这样取值,不是还得重新创建个遍历赋值。吐槽看来你对ES6的解构赋值掌握的还是不够彻底。如果想创建的变量名和对象的属性名不一致,可以这么写:
6 {; p: E+ G9 j S0 _
const {a:a1} = obj;
; ]3 s B* k' Z( a( b+ ]' d9 E
console.log(a1);// 1补充ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
, _) z+ h l) K4 H* J4 l
const {a,b,c,d,e} = obj || {};
复制代码
+ q6 a( g, ^3 F
二、关于合并数据的吐槽比如合并两个数组,合并两个对象。const a = [1,2,3];
1 D. j h5 x$ S5 Z
const b = [1,5,6];
7 Q' T/ _% ^9 K: ~) F
const c = a.concat(b);//[1,2,3,1,5,6]
) [6 }# s: [4 V7 z
const obj1 = {
( n( U, a4 N+ C# ]3 H; h0 x4 d
a:1,
' y, K' \4 X1 ~* |& R9 y
}
c0 v1 ~' O2 K, u/ p# T; t' X/ F F. c' I$ t
const obj2 = {
1 }2 {! k7 j1 Z% s2 k3 U5 E6 W
b:1,
. F. g8 k1 E" j, P! }( ?2 Z
}
" g8 V# w7 d( S
const obj = Object.assign({}, obj1, obj2);//{a:1,b:1}吐槽ES6的扩展运算符是不是忘记了,还有数组的合并不考虑去重吗?改进const a = [1,2,3];
: g) J' a: m i8 c2 n; m1 j
const b = [1,5,6];
6 D( A" r- `1 L2 \
const c = [...new Set([...a,...b])];//[1,2,3,5,6]
) o. p; j8 e& |- \. f' u
const obj1 = {
; n& ?' o% O- U
a:1,
4 [4 { l& {* g. Z5 H; ]$ |, j
}
* L. u. s9 d9 F8 }( ~
const obj2 = {
7 A" I4 v S( T' k- ]$ T: e
b:1,
. Y7 s/ W( f: H# I1 c& X
}
7 @# `. U( M0 v, ?- T: }: c; P8 O
const obj = {...obj1,...obj2};//{a:1,b:1}
复制代码
6 H) q' Y8 ~4 ~: m- Y$ S9 |8 @
三、关于拼接字符串的吐槽
/ g" F0 {. Y& ~, ~5 ]5 Q9 d5 |! _
const name = '小明';
% P% P" [3 \. p- M4 ?
const score = 59;
4 ]; W) U0 ?) [' Z5 ?6 }; w
let result = '';
, C8 \. {) ^9 c# ]2 p" Q- E; T
if(score > 60){
- i4 x0 B9 Z( \1 v) N2 ^
result = `${name}的考试成绩及格`;
) w" H' I4 T; Q. p( k* [- c7 \' @5 g
}else{
( ?) X+ s- D4 ?% s; e
result = `${name}的考试成绩不及格`;
" f, D( K4 M; M: _) l( S; I+ e7 v
}
复制代码
* H1 G) m; |. {
0 i+ i$ s* u4 U7 f( T
吐槽像你们这样用ES6字符串模板,还不如不用,你们根本不清楚在${}中可以做什么操作。在${}中可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。改进const name = '小明';
" u+ V% A% ?6 c/ ~) w9 i5 ]
const score = 59;
! A! D- D1 W) [) A3 Z
const result = `${name}${score > 60?'的考试成绩及格':'的考试成绩不及格'}`;
复制代码
; K9 i3 B& j7 n6 m% T5 I5 f
四、关于if中判断条件的吐槽if(
( H+ }) E; ~% a
type == 1 ||
0 h$ w" }: P1 t b/ j+ v
type == 2 ||
/ p. Z: c( }8 U) U: o. q) o
type == 3 ||
Q$ i5 d: A* {9 |4 k' Y0 ~
type == 4 ||
, Y1 |2 ^( G6 Z( \+ c" e+ P8 `
){
. P; o7 o: F) \) d2 E8 u# s; u$ m6 l
//...
$ T% ]& @0 m7 ]2 O8 q
}
复制代码
, \( i/ f/ {1 v
吐槽ES6中数组实例方法includes会不会使用呢?
: }* C+ D: ?7 J9 \0 Q
改进const condition = [1,2,3,4];
- o$ ~4 P1 L+ K" K. h
if( condition.includes(type) ){
, h# u% `/ y! s7 J
//...
' O0 V& G3 {2 K9 k
}
复制代码
. E5 d# G# k8 s T0 A
五、关于列表搜索的吐槽在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般用filter来实现。const a = [1,2,3,4,5];
. G5 K7 B8 @, f2 `" S b) V+ J
const result = a.filter(
. h1 J+ ]: y5 b! U, Z
item =>{
2 o0 {! h5 L% ?" i/ {0 w
return item === 3
) v ?7 \' e# a1 V: G0 T
}
1 V6 X, J3 e! t; n
)
复制代码
N2 E2 w' j x* D1 I1 L# D2 w9 Y$ p7 Z
吐槽如果是精确搜索不会用ES6中的find吗?性能优化懂么,find方法中找到符合条件的项,就不会继续遍历数组。改进const a = [1,2,3,4,5];
5 A$ i- T9 r3 L. T' M
const result = a.find(
' N) W2 ?6 K) a$ F" `
item =>{
7 d( t, ]! P' E9 z
return item === 3
4 _: T/ {% k( C: y: L" U) O/ s
}
) [( x! s4 n2 E/ d$ {
)
复制代码
# n9 g8 f" ]' G7 a
% f/ V( a: x0 R
六、关于扁平化数组的吐槽一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。
4 [% _' D! k! e `( T5 t3 x) \9 |
const deps = {
3 e' J/ p! r' s6 p
'采购部':[1,2,3],
* H4 w" l! O' Q+ s7 l% r
'人事部':[5,8,12],
1 Z% ]* n- a; A1 r, N( j4 u$ c
'行政部':[5,14,79],
! {/ z9 J* L' t; g
'运输部':[3,64,105],
! _, S# u: e" o L/ U* }
}
/ X- Z# o" n' z7 h
let member = [];
4 w: g/ N# Z" ]
for (let item in deps){
7 r8 G" y( w' r3 Y0 f) W- s' _
const value = deps[item];
3 H& _1 h0 _0 c i
if(Array.isArray(value)){
& k) m7 f, s' ?+ w
member = [...member,...value]
' u7 r% H6 @, V* A+ U6 r
}
) u# L, I' f* s1 B* s: |
}
1 {/ G- j! v' n2 h' m. g8 w
member = [...new Set(member)]
复制代码
; u3 L( H* R. m, t2 D
. p( ~! {+ Z( ~, Z3 E9 j
吐槽获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化?
+ W R8 [4 B" z" y6 }0 k$ o
改进
% W7 i. }5 s- J
const deps = {
; {5 g' [3 A `' ]- Q2 h6 |
'采购部':[1,2,3],
/ b9 {! r' j- T0 t' M
'人事部':[5,8,12],
1 F2 ~9 |- I- q" G
'行政部':[5,14,79],
( ^5 m; S/ v, e$ b' R
'运输部':[3,64,105],
$ d$ k- E E/ B
}
) n" M% C) T( [/ a
let member = Object.values(deps).flat(Infinity);
复制代码
' E# C$ b Y$ V& r7 j
其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。补充flat方法不支持IE浏览器。七、关于获取对象属性值的吐槽const name = obj && obj.name;吐槽ES6中的可选链操作符会使用么?改进const name = obj?.name;八、关于添加对象属性的吐槽当给对象添加属性时,如果属性名是动态变化的,该怎么处理。let obj = {};
# D, b4 p9 u) o4 n
let index = 1;
& a4 i; x6 f( ?& m6 h
let key = `topic${index}`;
% Q5 B+ G% ~% h% U6 F2 N4 d5 e8 W
obj[key] = '话题内容';吐槽为何要额外创建一个变量。不知道ES6中的对象属性名是可以用表达式吗?改进let obj = {};
& `$ T+ ?% v9 Z9 t3 \9 b* t" K6 j# _
let index = 1;
. A5 x- Q# U: B* I( z
obj[`topic${index}`] = '话题内容';
复制代码
( f, w+ M; M5 n n" ]+ r# F
1 r9 A. |' x! o! ^! L0 w# w
九、关于输入框非空的判断在处理输入框相关业务时,往往会判断输入框未输入值的场景。if(value !== null && value !== undefined && value !== ''){
" P( [8 P$ n( a8 z( M T: J% z( ]
//...
9 D7 k6 J. }2 Y( s/ n$ t
}
2 ? M( ~8 q5 V7 m- E
吐槽ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
) E4 w: u8 q2 L# u
if((value??'') !== ''){
0 `1 H+ a2 b8 M4 |2 C) Q1 n* X0 Y
//...
6 x% h: S, H# R h9 e- {; n9 i
}
. N' ^0 _/ O% s8 d8 X; o- f* y9 J% n
十、关于异步函数的吐槽异步函数很常见,经常是用 Promise 来实现。
. D. ~& @+ h t7 ? f8 ?$ e
const fn1 = () =>{
' h2 R7 `# C- I3 ~6 u
return new Promise((resolve, reject) => {
8 T2 `0 Q7 K! Y R+ V: v) @+ M! Y
setTimeout(() => {
; O8 L4 h) {* ]8 D8 G/ y
resolve(1);
9 y) [8 V7 w& R2 ~3 e3 R
}, 300);
3 ~* b$ o9 O5 i3 a
});
) h2 j8 u2 T1 f d
}
; m0 x. Z9 f) d' D
const fn2 = () =>{
. x" Q( R( r8 z5 D M' q. T7 {
return new Promise((resolve, reject) => {
* R( T' h4 L% _( r1 a
setTimeout(() => {
% k3 J3 l6 H# K: Z* o6 [
resolve(2);
. w2 y7 C( x! {+ x$ t, b
}, 600);
! a$ O/ H& l( @ d
});
$ ^+ p5 @& l3 ~
}
5 s" u1 ~* L C& X. ^
const fn = () =>{
( }" k) n& C) i
fn1().then(res1 =>{
3 Q0 G& x* W: k% b' N
console.log(res1);// 1
$ |* {: L+ F. \. h0 u4 H
fn2().then(res2 =>{
2 o9 f. y) J: _& l7 w' b
console.log(res2)
! E7 p2 ]$ R- F. {
})
) P% L/ q4 x2 h) C2 f% P* M
})
. h' q- z) n2 C
}
复制代码
( l1 n% z1 U( Q( f
吐槽如果这样调用异步函数,不怕形成地狱回调啊!改进
; Y$ X2 O( o8 Y5 Q. j! ^
const fn = async () =>{
9 z- `' I7 q5 E3 f
const res1 = await fn1();
+ A X3 z7 Y. W3 O. X
const res2 = await fn2();
9 @: W2 K8 C, w O
console.log(res1);// 1
7 D$ q, M! P0 @$ E- h
console.log(res2);// 2
: [: \5 T3 G; B" S8 z0 J
}
复制代码
$ R( R# V9 P/ k
补充但是要做并发请求时,还是要用到
. h/ C+ c: i( J; L8 b2 Q) q5 C- r2 T
Promise.all()
, x- v; p: n! y
const fn = () =>{
7 H( X) J* g! c% r+ M/ `
Promise.all([fn1(),fn2()]).then(res =>{
3 U3 c L+ m8 `# j5 w' A+ g; I
console.log(res);// [1,2]
- Q A- s# r2 o0 u2 O
})
9 W$ V9 t, T, n: q! J& h
}
复制代码
4 _% j! w# a5 `* y B( F! Q" N. ]
如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()。
8 I2 Y. A0 R. F- w
十一、后续欢迎来对以上十点leader的吐槽进行反驳,你的反驳如果有道理的,下次代码评审会上,我替你反驳。此外以上的整理内容有误的地方,欢迎在原文评论中指正,万分感谢。
7 Q! T2 J# [) w, A5 _6 Z
; z9 D4 t9 m5 H& B% t5 n
+ d/ P% t8 S2 y) }1 \6 b
/ l4 K n; s9 Z S
欢迎光临 漫潮者,私有云,NAS,新媒体电商.软件开发,商乾 (https://www.aurrel.com/)
Powered by Discuz! X3.5