前端代码如何更加简洁
很多人写代码的时候随心所欲,想着这是自己写的,到时候肯定可以维护。可事实上,自己去回看的时候,也会看感叹这写的是啥呀!为了方便自己以后维护,以及后面的人能够更快的阅读你的代码,我们每个人都应该对自己的代码有洁癖。本文主要讨论代码的可读性、可拓展性、可复用性,最终目的是让别人看完你的代码,不会说这写的是啥呀!
典型案例
1.常量没有申明
不要凭空出现一个常量,都应该命名,并且大写
Bad
getNewDateFormat(info.startData, 864000)
Good
const ONE_DAY_TIME= 24 * 3600;
getNewDateFormat(info.startData, ONE_DAY_TIME)
2.命名不够简洁
减少一些无意义的前缀
Bad
const user = {
userName:'张三',
userAge:25,
}
Good
const user = {
name:'张三',
age:25,
}
3.没有意义的命名,并且函数没有默认值
命名都得通俗易懂,千万不要a,b,看完函数名称不能很准确的知道其作用
Bad
function getDate(date, format) {
}
const date = new Date();
const format = "yyyy-MM-dd hh:mm:ss";
const d = getDate(date, format);
Good
function getDateFormat(date, format = "yyyy-MM-dd hh:mm:ss") {
}
const date = new Date();
const currentDate = getDateFormat(date);
4.多行字符串处理不够简洁
用``处理会更加整洁
Bad
const data = '2022 新年快乐 \n\t'
+ '新的一年要赚更多的钱 \n\t'
Good
const data = `2022 新年快乐
新的一年要赚更多的钱 ` ;
5.函数的参数太多
函数有N多个参数,传参数的时候很不灵活
Bad
function request(url,method='get',data,params) {
}
Good
function request({ url,method='get',data,params }) {
}
6.违反函数的单一性原则
很多人一个函数做太多事情,一大堆代码都在里面,很难观看
Bad
function notify(users) {
users.map(user => {
const record = DB.find(user);
if (record.isActive()) {
sendMessage(user);
}
});
}
Good
function isActive(user) {
const record = DB.find(user);
return record.isActive();
}
function notify(users) {
users.filter(isActive).forEach(sendMessage);
}
7.没有使用函数式编程
很多人依旧使用命令式编程,函数式变编程可以让代码的逻辑更清晰更优雅
Bad
const heroMoneyList = [
{
name: 'AM',
money: 30000,
},{
name: 'SF',
money: 24000
},{
name: 'SK',
money: 18000
},{
name: 'LINA',
money: 14000
},{
name: 'BANE',
money: 9000
},
]
let totalMoney = 0;
for (let i = 0; i < heroMoneyList.length; i++) {
totalMoney += heroMoneyList[i].money;
}
Good
const heroMoneyList = [
{
name: 'AM',
money: 30000
},{
name: 'SF',
money: 24000
},{
name: 'SK',
money: 18000
},{
name: 'LINA',
money: 14000
},{
name: 'BANE',
money: 9000
},
]
let totalMoney = heroMoneyList
.map(hero => hero.money)
.reduce((moneys, money) => moneys + money, 0)
8.没有提前return,导致代码结构太复杂
提前return可以使代码看起来更加简洁
Bad
this.$refs['form'].validate((valid) => {
if (valid) {
let httpData = { ...this.saveAssetForm(this.form) }
this.$request(httpData).then((res) => {
if (res.result === 'success') {
this.$message.success('提交成功!')
this.dialogShow = false
this.$refs['form'].resetFields()
this.$emit('save-success')
} else {
this.$message.error('提交失败')
}
})
} else {
return false
}
})
Good
this.$refs['form'].validate(handleSubmit(valid))
function handleSubmit(valid){
if(!valid){
retrun false
}
let httpData = { ...this.saveAssetForm(this.form) }
this.$request(httpData).then((res) => {
if (res.result !== 'success') {
this.$message.error('提交失败')
return false
}
this.$message.success('提交成功!')
this.dialogShow = false
this.$refs['form'].resetFields()
this.$emit('save-success')
})
}
9.if语句太多了
很多if判断可以通过array,Obj的判断给替换掉
Bad
if(this.staus === 1 || this.status === 2 || this.status === 4){
...
}
function pick(color) {
if (color === 'red') {
return ['apple', 'strawberry'];
} else if (color === 'yellow') {
return ['banana', 'pineapple'];
} else if (color === 'purple') {
return ['grape', 'plum'];
} else {
return [];
}
}
Good
const successStatus = [1,2,4];
if(successStatus.includes(this.status)){
...
}
const fruits = [
{name: 'apple', color: 'red'},
{name: 'strawberry', color: 'red'},
{name: 'banana', color: 'yellow'},
{name: 'pineapple', color: 'yellow'},
{name: 'grape', color: 'purple'},
{name: 'plum', color: 'purple'}
];
function pick(color) {
return fruits.filter(f => f.color == color);
}
10.还在使用回调函数
赶快抛弃回调函数,使用promise或者Async/Await
Bad
this.$request('api/money/get', (response,requestErr) => {
if(requestErr){
return console.error(requestErr)
}
this.$request('api/spend-money',response.money, (result,error) => {
if(error){
return console.error(error)
}
console.log('success');
})
})
Good
this.$request('api/money/get')
.then(response) => {
return this.$request('api/spend-money',response.money);
})
.then((result) => {
console.log('success');
})
.catch((err) => {
console.error(err);
});
Good
async function spendMoney() {
try {
const response = await this.$request('api/money/get');
await this.$request('api/spend-money',response.money);
console.log('success');
} catch(err) {
console.error(err);
}
}
简洁技巧
1.多使用三元运算符
三元运算符也能实现函数的直接调用
使用前
if (hungry){
eat();
}else{
run();
}
使用后
hungry ? eat() : run() ;
2.对象结构可以简写
三元运算符也能实现函数的直接调用
使用前
const name = '周杰伦';
const job = '歌手';
let human = {name:name, job:job};
使用后
const name = '周杰伦';
const job = '歌手';
let human = {name, job};
3.申明变量简写
使用前
let name;
let age;
let money = 100;
使用后
let name, age, money = 100;
4.短路判断赋默认值
使用前
let money
if(user.money) {
money = user.money;
}else{
money = 100;
}
使用后
let money = user.money || 100;
5.使用箭头函数
使用尖头函数会更加简洁,而且不会改变this的指向
使用前
setTimeout(function() {
sendMessage();
},10000);
使用后
setTimeout( () =>sendMessage() ,10000);
6.使用ES6模板字符串
模板字符串对字符串的拼接处理会更加友好
使用前
let name = '周杰伦';
let job = '歌手';
let works - '七里香'
let words = '我是'+ name + ',我的工作是' + job + ',我的代表作是' + works +'。';
使用后
let name = '周杰伦';
let job = '歌手';
let works - '七里香'
let words = `我是${name},我的工作是${job},我的代表作是${works}。`;
7.使用展开操作符...
展开操作符能使数组和对象的操作能够更简单
使用前
let jayChouSongs = ['七里香', '夜曲', '搁浅', '一路向北'];
let maydaySongs = ['突然好想你', '我不愿让你一个人' , '咸鱼', '后来的我们'];
let songs = jayChouSongs.concat(maydaySongs);
使用后
let jayChouSongs = ['七里香', '夜曲', '搁浅', '一路向北'];
let maydaySongs = ['突然好想你', '我不愿让你一个人' , '咸鱼', '后来的我们'];
let songs = [...jayChouSongs, ...maydaySongs];
8.接受多个接口返回结果
我们在'/user'接口中获取用户个人信息,'/songs'接口中获取歌曲信息
async function getUserSongs(){
return await Promise.all([
fetch('/user'),
fetch('/songs')
]);
}
const [user, songs] = getUserSongs();
9.使用可选链?.
当某个对象我们需要去判断是null或者undefined在辅助的时候,使用可选链会更加方便
使用前
let name = '张三';
if(info && info.name){
name = info
}
使用后
let name = info?.name || '张三';
10.数组操作
有些人还在使用for循环做一些数组的操作,js Array的很多原生函数会大大提升简洁度
1.通过filter()函数进行数组筛选符合条件的所有值
const users = [{name:'张三', age:30},{name:'李四', age:35},{name:'王5', age:12}];
const result = users.filter(user => user.age > 20); // [{name:'张三', age:30},{name:'李四', age:35}]
2.通过find()函数进行数组筛选符合条件的第一个值
const users = [{name:'张三', age:30},{name:'李四', age:35},{name:'王5', age:12}];
const found = users.find(user => user.age > 20); // {name:'张三', age:30}
3.使用reduce() 方法进行统计
let lists = [
{singer:'jayChou', song:'夜曲'},
{singer:'mayday', song:'倔强'},
{singer:'mayday', song:'如烟'},
{singer:'yoga', song:'说谎'},
];
let userSongs = lists.reduce((result, currentList) =>{ // result 累计值 currentList 当前值
result[currentList.singer] = result[currentList.singer] ? ++result[currentList.singer] : 1;
return result;
}, {});
// {jayChou: 1, mayday: 2, yoga: 1}
4.使用new Set()去重
let userLists = ['张三','jaychou', '张三', '李四'];
let users = [...new Set(userLists)]; // ['张三','jaychou', '李四'];
5.通过Math.max() 配合map() 查询数组对象中的最值
const users = [{name:'张三', age:30},{name:'李四', age:35},{name:'王5', age:12}];
Math.max.apply(Math, users.map(user => user.age)) // 35 最小值只需要把max改成min
6.通过some()判断数组中是否有元素 满足次条件,every()判断是否都满足,返回值为boolean
const users = [{name:'张三', age:30},{name:'李四', age:35},{name:'王5', age:12}];
users.some(user => user.age<20); // true
users.every(user => user.age<20); // false
11.对象操作
1.通过Object.keys和Object.values分别获取对象所有的key值和value值
const user = {
name: 'jayChou',
job: 'singer',
song: '七里香'
};
let userKeys = Object.keys(user); //['name', 'job', 'song']
let userValues = Object.values(user); //['jayChou', 'singer', '七里香']
2.通过Object.entries把对象转换成key/value对数组
const user = {
name: 'jayChou',
job: 'singer',
song: '七里香'
};
let userKeys = Object.entries(user); //[['name','jayChou'],['job', 'singer'], ['song', '七里香']]
3.通过结构赋值过滤对象属性
const {address, ...user} = {
name: 'jayChou',
job: 'singer',
song: '七里香',
address: '台湾'
};
console.log(user) // {name: 'jayChou',job: 'singer',song: '七里香'}
转载自:https://juejin.cn/post/7063386798403584008