0%

javascript-refactor-use-map-isteadof-push

介绍

最近在做Code review的时候,发现很多使用Array.prototype.push的代码,都可以使用Array.prototype.map来重构。使用map可以使代码更简洁、更易读。

示例

下面是一个使用push来返回User对象的例子,逻辑很简单,根据传入的userList,返回一个简化的User对象列表。函数内部首先定义了一个空数组result,然后使用forEach遍历userList,如果满足条件,就将简化的User对象推入result数组中。最后返回这个result数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
const buildUserList = (userList: User[]) => {
let result: SimplifiedUser[] = [];
userList.forEach((user: User) => {
if (user.accountCode === '' || user.accountCode === null) {
result.push({
department: user.department,
userCode: user.username,
userName: user.fullName
});
}
});
return result;
}

这种写法很常见,也算中规中矩吧,但是有一些弊端:

  1. 需要额外维护一个结果数组result
  2. 数据的过滤和转换混合在了一起。
  3. 属于命令式编程的写法。

现在我们使用map来改写一下,对于第一个if判断,我们可以使用filter来提取满足条件的用户,然后使用map来转换成简化的User对象。这样就可以直接返回一个新的数组,而不需要手动创建和推入元素。

1
2
3
4
5
6
7
8
9
const buildUserList = (userList: User[]) => {
return userList
.filter((user: User) => user.accountCode === '' || user.accountCode === null)
.map((user: User) => ({
department: user.department,
userCode: user.username,
userName: user.fullName
}));
};

现在代码简洁了不少,但是filter中的条件有点长,我们可以将其提取成一个函数来提高可读性。

1
2
3
4
5
6
7
8
9
10
11
12
13
const isUserWithoutAccountCode = (user: User) => {
return user.accountCode === '' || user.accountCode === null;
};

const buildUserList = (userList: User[]) => {
return userList
.filter(isUserWithoutAccountCode)
.map((user: User) => ({
department: user.department,
userCode: user.username,
userName: user.fullName
}));
};

甚至map中的转换逻辑也可以提取成一个函数,这样代码会更清晰。

1
2
3
4
5
const simplifyUser = (user: User): SimplifiedUser => ({
department: user.department,
userCode: user.username,
userName: user.fullName
});

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const isUserWithoutAccountCode = (user: User) => {
return user.accountCode === '' || user.accountCode === null;
};

const simplifyUser = (user: User): SimplifiedUser => ({
department: user.department,
userCode: user.username,
userName: user.fullName
});

const buildUserList = (userList: User[]) => {
return userList
.filter(isUserWithoutAccountCode)
.map(simplifyUser);
};

重构后的代码有如下好处:

  1. 逻辑清晰,简洁易懂,读起来更加顺畅。
  2. 数据的过滤和转换分离,职责单一,方便测试和维护。
  3. 使用了函数式编程的风格,符合现代JavaScript的编程习惯。

总结

什么是好代码?大概就是这个样子吧,为什么有些人的代码读起来通俗易懂,而有些人的代码读起来却像天书?这就是差距。我喜欢将其成为代码气质,我们一定要培养出自己的代码气质。

昨天组里聚餐,喝了几瓶啤酒,总算睡了一个好觉,这几天隔壁的猫天天叫,我每晚只能睡四五个小时,白天困得不行,已经好几天没有提PR了,下周要加油了!