一、代码整洁推荐
1.1 三元(三目)运算符
如果只想在一行中编写if…else语句时,这是一个很好的节省代码的方式。
常规:
const x = 20 let answer if(x > 10) { answer = '大于10' }else { answer = '小于等于10' }
简写:
const x = 20 const answer = x > 10? '大于10' : '小于等于10'
嵌套版三元运算:
const x = 20 const answer = x > 10? '大于10' : x < 5? '小于5' : '在5和10之间' // 第二层加上()增强可读性 const answer = x > 10? '大于10' : (x < 5? '小于5' : '在5和10之间')
注意:三元运算不要超过2层嵌套,否则可读性不强,如果是嵌套两层,要求第二层加上()帮助提升可读性。
1.2 短路判断简写
将变量值分配给另一个变量时,可能希望确保源变量不为null,undefined或为空。这时候可以编写带有多个条件的长 if 语句,也可以使用短路判断。
常规:
if(type !== null || type !== undefined || type !== '') { let wtType = type } else { let wtType = '01' }
简写:
let wtType = type || '01'
注意:如果type值为false或者数字0将取值为字符串’01’。
1.3 变量声明简写
在进行连续性的变量声明操作时,应尽可能的使用 一次声明语句来提升程序运行效率。
常规:
let x let y let z = 1
简写:
let x, y, z = 1
1.4 if真值判断简写
这可能是微不足道的,但值得一提。在执行“if 检查”时,有时可以省略全等运算符。
常规:
if(likeJavascript === true) { ... } if(likeNode !== true) { ... }
简写:
if(likeJavascript) { ... } if(!likeNode) { ... }
1.5 For循环简写
常规:
const arr = [1, 2, 3] for(let i = 0; i < arr.length; i++) { console.log(i, arr[i]) if(arr[i] > 1) { break } } // 0, 1 // 1, 2
如果不需要访问索引,请执行以下操作:
for(let item of arr) { console.log('item', item) if(item > 1) { break } } // 1 // 2
如果只想访问索引,请执行以下操作:
for(let index in arr) { console.log(index) } // 1 // 2 // 3
如果要访问对象中的键,请执行以下操作
const obj = {name: 'zhangsan', age: 18} for(let key in obj) { console.log(key,obj[key]) } // name // age
注意:不能使用for…of 来遍历对象。
1.6 对象属性简写
ES6提供了一种更简单的方法来为对象分配属性。如果变量名称与对象键相同,则可以使用简写表示法。
常规:
let signType = '1' let params = { signType: signType }
简写:
let signType = '1' let params = { signType }
1.7 箭头函数简写
经典函数以简单的形式易于读写,但是一旦你开始将它们嵌套在其他函数调用中,它们往往会变得有点冗长和混乱。
常规:
function sayHello(name) { console.log('Hello', name) } setTimeout(function() { console.log('Loaded') }, 2000) list.forEach(function(item) { console.log(item) })
简写:
const sayHello = name => console.log('Hello', name) setTimeout(() => console.log('Loaded'), 2000) list.forEach(item => console.log(item))
1.8 隐式返回简写
Return 是我们经常使用的关键字,用于返回函数的最终结果。具有单个语句的箭头函数将隐式返回其执行结果(函数可以省略大括号{}用()省略return关键字,具体可参考下例)。
要返回多行语句(例如对象),必须使用 () 而不是 {} 来包装函数体。这可确保将代码执行为单个语句。
常规:
function sum(x, y) { return x + y } function makeInfo(name, age) { return {name, age} }
简写:
const sum = (x, y) => x + y const makeInfo = (name, age) => ({name, age})
1.9 模板字符串
您是否厌倦了使用 ‘+’ 将多个变量连接成一个字符串?有没有更简单的方法?如果你能够使用ES6,那么你很幸运。您需要做的就是使用反引号,并使用 ${} 来包含变量。
常规:
const name = 'zhangsan' const age = 18 let des = name + '今年' + age + '岁'
简写:
const name = 'zhangsan' const age = 18 let des = `${name}今年${age}岁`
1.10 默认参数值
您可以使用if语句定义函数参数的默认值。在ES6中,您可以在函数声明本身中定义默认值。
常规:
function volume(l, w, h) { if(w === undefined) { w = 3 } if(h === undefined) { h = 4 } return l * w * h }
简写:
const volume = (l, w = 3, h = 4) => l * w * h volume(2) // 24
注意:只有w,h为undefined时默认值才会生效。
结构赋值中的默认值也是如此,如果值为null默认值不会生效,如:
const res = { list: null, code: undefined } const { list = [], code = 1 } = res console.log(list) // null console.log(code) // 1 let num = list.length // Uncaught TypeError: Cannot read properties of null (reading 'length')
注意:如果直接取list数组的长度或者利用[index]取里面的值在res.list为null或者不为数组的时候可能会发生报错,针对该问题,大家可以在解构的时候不赋默认值,在解构的下方利用null判断运算符来处理默认值,如:
const res = { list: null } let { list , code = 1 } = res list = list ?? [] console.log(list) // [] let num = list.length // 0
1.11 解构赋值简写
对数组和变量进行解构可以减少变量滥用,提升程序的运行效率。
常规:
let params = { wtId: this.transferDetail.wtId, newPic: type === '01' ? this.selectPersonId : '', // type是方法入参 oldPic: this.transferDetail.picOld, recordId: this.applyId, // 转派记录 replacementPicStatus: '02', // 转派状态 01-转派中 02-转派结束 replacementReason: this.replacementReason }
简写:
const { selectPersonId, applyId, replacementReason, transferDetail } = this let params = { wtId: transferDetail.wtId, newPic: type === '01' ? selectPersonId : '', // type是方法入参 oldPic: transferDetail.picOld, recordId: applyId, // 转派记录 replacementPicStatus: '02', // 转派状态 01-转派中 02-转派结束 replacementReason }
解构知识点链接地址:https://es6.ruanyifeng.com/#docs/destructuring
1.12 多条件判断简写
常规:
function typeHandle(type) { if (type === 'test1') { test1(); } else if (type === 'test2') { test2(); } else if (type === 'test3') { test3(); } else if (type === 'test4') { test4(); } else { throw new Error('Invalid value ' + type); } } typeHandle('test3')
简写:
function typeHandle(type) { const types = { test1: test1, test2: test2, test3: test3, test4: test4 }; let func = types[type]; (!func) && throw new Error('Invalid value ' + type); func(); } typeHandle('test3')
1.13 多变量赋值简写
常规:
let test1, test2, test3; test1 = 1; test2 = 2; test3 = 3; let name, age, sex; name = 'zhangsan'; age = '18'; sex = '男'
简写:(利用es6数组、对象的结构赋值,实现多变量赋值简写)
let [test1, test2, test3] = [1, 2, 3]; let {name, age, sex} = { name: 'zhangsan', age: '18', sex: '男'};
1.14 解构时重命名
常规:
const { ticketTypeName } = this.tciketDetail let params = { wtName: ticketTypeName, ... }
简写:
const { ticketTypeName: wtName } = this.tciketDetail let params = { wtName, ... }
对象解构赋值的简写形式:
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; baz // "aaa" foo // error: foo is not defined
1.15 对象替代switch
常规:
// 获取工作票名称 workTicketName(type) { switch (type) { case '01': return '变一' break case '02': return '变二' break case '03': return '配一' break case '04': return '配二' break case '05': return '低压' break case '06': return '作业卡' break case '07': return '派工单' break default: break } } workTicketName('01') // 变一
简写:
// 获取工作票名称 workTicketName(type) { const typeObj = { '01': '变一', '02': '变二', '03': '配一', '04': '配二', '05': '低压', '06': '作业卡', '07': '派工单' } return typeObj[type] } workTicketName('01') // 变一
1.16 链判断运算符
编程实务中,如果读取对象内部的某个属性,往往需要判断一下,属性的上层对象是否存在。比如,读取message.body.user.firstName
这个属性,安全的写法是写成下面这样。
// 错误的写法 const firstName = message.body.user.firstName || 'default'; // 正确的写法 const firstName = (message && message.body && message.body.user && message.body.user.firstName) || 'default'; // 但是这种写法如果层级过长会显得冗长,可读性也不强,这是我们可以利用链判断运算符来解决 //链判断运算符写法 const firstName = message?.body?.user?.firstName || 'default';
链判断运算符?.
有三种写法。
obj?.prop
// 对象属性是否存在obj?.[expr]
// 同上 也可以理解为 arr?.[index]func?.(...args)
// 函数或对象方法是否存在
下面是?.
运算符常见形式,以及不使用该运算符时的等价形式。
a?.b // 等同于 a == null ? undefined : a.b a?.[x] // 等同于 a == null ? undefined : a[x] a?.b() // 等同于 a == null ? undefined : a.b() a?.() // 等同于 a == null ? undefined : a()
常规:
// 计划 id let planId = this.ticketDetail && this.ticketDetail.planDetailVoList && this.ticketDetail.planDetailVoList[0] && this.ticketDetail.planDetailVoList[0].planId
简写:
// 计划 id let planId = this.ticketDetail?.planDetailVoList?.[0]?.planId // 如果任意一个问号前面的值为null或者undefined都将直接返回undefined,不在向下取值
注意:链判断运算符只能在js代码块中使用,不能在template里面的标签上使用,否则会解析报错,如果想要在template里达到上述简写效果可以在计算属性中使用。
// 错误的写法 <template> <div class="wrap"> <span>计划编号:</span> {{ ticketDetail && ticketDetail.planDetailVoList && ticketDetail.planDetailVoList[0] && ticketDetail.planDetailVoList[0].planNo || '' }} </div> </template> <script> export default { data() { return { ticketDetail: { planDetailVoList: [ { planNo: 'T202304200940' // 计划编号 } ] } } } } </script> //正确的写法 <template> <div class="wrap"> <span>计划编号:</span> {{ planNo }} </div> </template> <script> export default { data() { return { ticketDetail: { planDetailVoList: [ { planNo: 'T202304200940' // 计划编号 } ] } } }, // 计算属性 computed: { // 计划编号 planNo({ticketDetail}) { return ticketDetail?.planDetailVoList?.[0]?.planNo || '' } } } </script>
链判断运算符知识点链接:https://es6.ruanyifeng.com/#docs/operator
1.17 Null 判断运算符
读取对象属性的时候,如果某个属性的值是null
或undefined
,有时候需要为它们指定默认值。常见做法是通过||
运算符指定默认值。
const headerText = response.settings.headerText || 'Hello, world!'; const animationDuration = response.settings.animationDuration || 300; const showSplashScreen = response.settings.showSplashScreen || true;
上面的三行代码都通过||
运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为null
或undefined
,默认值就会生效,但是属性的值如果为空字符串或false
或0
,默认值也会生效。
为了避免这种情况,ES2020 引入了一个新的 Null 判断运算符??
。它的行为类似||
,但是只有运算符左侧的值为null
或undefined
时,才会返回右侧的值。
const headerText = response.settings.headerText ?? 'Hello, world!'; const animationDuration = response.settings.animationDuration ?? 300; const showSplashScreen = response.settings.showSplashScreen ?? true;
上面代码中,默认值只有在左侧属性值为null
或undefined
时,才会生效。