使用解构赋值简化变量声明
tsx
const obj = {
a:1,
b:2,
c:3,
d:4,
e:5,
}
// 不好的写法
const a = obj.a;
const b = obj.b;
const c = obj.c;
const d = obj.d;
const e = obj.e;
// 我推荐的
const {a: newA = '',b,c,d,e} = obj || {};
- 要注意解构的对象不能为
undefined
、null
。否则会报错。所以可以给个空对象作为默认值 - 解构的 key 如果不存在,可以给个默认值,避免后续逻辑出错
合并数据
tsx
const a = [1,2];
const b = [3,4];
const obj1 = {
a:1,
}
const obj2 = {
b:1,
}
// 一般的写法
const c = a.concat(b);
const obj = Object.assign({}, obj1, obj2);
// 我推荐的写法
const c = [...arr1, ...arr2];
const obj = { ...obj1, ...obj2 };
Object.assign 和 Array.concat 其实也可以,只不过拓展运算符
的优势如下:
- 更简洁,阅读性更好
- 会创建新的对象/数组,不会污染原数据(避免副作用)
- 支持深层次嵌套结构的合并
- 类型安全,编译时检查
条件判断
条件判断的话有几种情况,第一种是常见的多个条件判断
tsx
// 不好的写法
if(
type == 1 ||
type == 2 ||
type == 3 ||
type == 4 ||
){
//...
}
// 我推荐的
const typeArr = [1,2,3,4]
if (typeArr.includes(type)) {
//...
}
这样写代码会更简洁。如果其他地方也有相同的条件判断逻辑,当需要同时修改时,只需要修改 typeArr 即可。
第二种是三目运算符的条件判断,三目运算符我个人认为如果是简单的判断可以写,但是稍微复杂或着未来会改动的判断,最好不要使用三目运算符。容易三目运算符无限嵌套
tsx
let c = 1, d = 2, e = 3
// 不好的写法
const obj = {
a: 1,
b: (c === 1 || d === 1) ? 'bb' : d === 2 ? 'vv' : e === 3 ? '66' : null
}
// 我推荐的写法1
const obj = {
a: 1,
}
if (c === 1 || d === 1) {
obj.b = 'bb'
} else if (d === 2) {
obj.b = 'vv'
} else if (e === 3) {
obj.b = '66'
} else {
obj.b = null
}
// 我推荐的写法2
const valueMap = [
{ condition: (c, d, e) => c === 1 || d === 1, value: 'bb' },
{ condition: (c, d, e) => d === 2, value: 'vv' },
{ condition: (c, d, e) => e === 3, value: '66' }
];
function getValueByMap(c, d, e) {
const match = valueMap.find(item => item.condition(c, d, e));
return match ? match.value : null;
}
getValueByMap(c, d, e
// 我推荐的写法3
const conditionConfig = {
rules: [
{ name: 'rule1', check: (c, d, e) => c === 1 || d === 1, result: 'bb' },
{ name: 'rule2', check: (c, d, e) => d === 2, result: 'vv' },
{ name: 'rule3', check: (c, d, e) => e === 3, result: '66' }
],
defaultValue: null
};
function evaluateConditions(c, d, e, config) {
for (const rule of config.rules) {
if (rule.check(c, d, e)) {
return rule.result;
}
}
return config.defaultValue;
}
evaluateConditions(c, d, e, conditionConfig)
写法1、写法2、写法3都可以,具体可以看团队代码规范。
一般来说,写法1适用于比较简单的条件判断,比如请求参数时,可能会不同的情况添加额外的参数
写法2适用于条件比较多的情况
写法3使用于条件判断经常改的情况,这种情况可以使用配置化的方式封装条件判断。(ps:甚至在后续迭代时,如果产品跟你battle,你可以拿代码怼回去。兜底留痕)
纯函数
最好一个函数只做一件事,可以组合可以拆分
tsx
// 不好的写法
function createObj(name, temp) {
if (temp) {
fs.create(`./temp/${name}`);
} else {
fs.create(name);
}
}
// 我推荐的写法
function createFile(name) {
fs.create(name);
}
function createTempFile(name) {
createFile(`./temp/${name}`)
}
不好的写法不满足纯函数
的概念,相同的输入有了不同的输出
再举一个例子:
tsx
//不好的写法
function emailClients(clients) {
clients.forEach((client) => {
const clientRecord = database.lookup(client);
if (clientRecord.isActive()) {
email(client);
}
});
}
//我推荐的写法
function emailClients(clients) {
clients
.filter(isClientRecord)
.forEach(email)
}
function isClientRecord(client) {
const clientRecord = database.lookup(client);
return clientRecord.isActive()
}
这样写逻辑更清晰,易读。
- 巧用filter函数,把filter的回调单开一个函数进行条件处理,返回符合条件的数据
- 符合条件的数据再巧用forEach,执行email函数
函数参数个数不要超过2个
就我个人而言,当函数的参数个数超过2个时,我会以对象的形式作为参数传入
tsx
// 不好的写法
function create(p1, p2, p3, p4) {
// ...
}
create(1,'2',true,[])
// 我推荐的写法
const config = {
p1: 1,
p2: '2',
p3: true,
p4: []
}
function create(config) {
}
create(config)
这样写在调用函数时,代码更简洁,可读性更好。
获取对象属性值
tsx
// 不好的写法
const name = obj && obj.name;
// 我推荐的写法
const name = obj?.name;
可选链让语法更简洁
箭头函数简化
tsx
// 传统函数定义
function add(a, b) {
return a + b;
}
// 箭头函数简化
const add = (a, b) => a + b;
需要注意的时,如果函数体涉及到了 this,则需要注意箭头函数 this 的指向问题
简化函数参数
tsx
// 不好的写法
function greet(name) {
const finalName = name || 'Guest';
console.log(`Hello, ${finalName}!`);
}
// 我推荐的写法
function greet({ name = 'Guest' }) {
console.log(`Hello, ${name}!`);
}
过滤操作
前端一般会涉及到过滤操作,比如精准过滤
tsx
const a = [1,2,3,4,5];
// 不好的写法
const result = a.filter(
item => {
return item === 3
}
)
// 我推荐的写法
const result = a.find(item => item === 3)
find相较于 filter 来说,有结果时不会继续遍历数组,性能更好
非空条件判断
有些时候,我们要判断值是否是 null、undefined 时,可以通过 ??
判断
tsx
// 一般的写法
if (a !== null && a !== undefined) {
const b = 'BBBB'
}
// 我推荐的写法
const b = a ?? 'BBBB'
??
运算符是当左侧是 null 或者 undefined 时,会取右侧的值
注释
在适当的地方写上注释,方便后续迭代