避免意外的值促成了意外的结果
在下面的代码中,我们的目的是判断草稿中的邀请人和当前邀请人是否为同一个人,但这里存在潜在的问题,如果draftInviterUserId和inviterUserId的值并非是我们期望的值,而是undefined、null或空字符串,那这个条件也会成立,但结果将会带来bug。
bad
const isSameInviter = draftInviterUserId === inviterUserId;
bood
const isValidValue = (value) => {
// 这里我们没有使用!!value,而是使用冗余的方案,是为了避免在语法上会被转换为假值,但在业务上是合法的值,比如0
return id !== undefined && id !== null && id !== ''
}
const isSameInviter = () => {
if (!isValidValue(draftInviterUserId) || !isValidValue(invterUserId)) {
return false
}
return draftInviterUserId === inviterUserId
}
从上面来看,一个简单的相等比较,其中就存在2个容易被忽略陷阱。
避免重复判断
bad
if (currentTheme?.id && currentTheme?.id === 'xxx') {
// do something
}
good
if (currentTheme?.id && currentTheme.id === 'xxx') {
// do something
}
currentTheme.id在前面已经使用?.进行了判断,后面没必要再次判断一遍
tip:
使用?.操作符的目的是为了安全地访问currentTheme可能为null或undefined的情况
因为当currentTheme为null或undefined,直接访问currentTheme.id会抛出错误,使用?.操作符,表达式会返回undefined而不是抛出错误
变量声明位置
bad
const query = {
...
}
if (type === '1') {
api.getListData(query)
} else {
api.getData()
}
good
if (type === '1') {
const query = {
...
}
api.getListData(query)
} else {
api.getData()
}
- 变量作用域最小化原则:query 只在 if 分支中使用,不需要在 else 分支中使用,因此应该将其定义在实际需要的作用域内。
- 代码可读性:将相关的代码放在一起,使逻辑更清晰和内聚。
- 避免不必要的内存占用:当走 else 分支时,不需要创建 query 对象。
对象常量
bad
/**
* 主题类型枚举
* @readonly
* @enum {number}
* @property {number} LANDMARK - 地标类型
* @property {number} VILLAGE - 村庄类型
* @property {number} MIXED - 地标和专题的混合类型
*/
export const THEME_TYPES = {
LANDMARK: 0,
VILLAGE: 1,
MIXED: 2,
};
good
/**
* 主题类型枚举
* @readonly
* @enum {number}
* @property {number} LANDMARK - 地标类型
* @property {number} VILLAGE - 村庄类型
* @property {number} MIXED - 地标和专题的混合类型
*/
export const THEME_TYPES = Object.freeze({
LANDMARK: 0,
VILLAGE: 1,
MIXED: 2,
});
即使是const声明对象也会能够被意外赋值,使用Object.freeze就可以避免
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。