鏈判斷運算符
ES5
我們判斷一個深層級的對象是否有某一個 key
需要一層一層去判斷,現在我們可以通過?.
的方式去獲取
// es5
// 錯誤的寫法(當某一個key不存在undefined.key就會代碼報錯)
const firstName = message.body.user.firstName;
// 正確的寫法
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
// es6
const firstName = message?.body?.user?.firstName || 'default';
鏈判斷運算符的三種用法,?.
運算符相當於一種短路機制,只要不滿足條件,就不再往下執行
obj?.prop
// 對象屬性obj?.[expr]
// 對象屬性func?.(...args)
// 函數或對象方法的調用
Null 運算判斷符
讀取對象屬性的時候,如果某個屬性的值是 null
或 undefined
,有時候需要爲它們指定默認值,常見做法是通過 ||
運算符指定默認值
(null || undefined) ?? 1 // => 1
??
運算符沒有 ||
健壯,只針對 null
或 undefined
進行默認值設置,且存在運算優先級問題,與其他一元操作符配合使用需要用括號表明優先級
Map 對象
Map 對象在實際的業務場景中,多用於抽離複雜邏輯判斷,在一元條件判斷無法滿足的情況下
將判斷條件作爲對象的屬性名,將處理邏輯作爲對象的屬性值,在按鈕點擊的時候,通過對象屬性查找的方式來進行邏輯判斷, 時間複雜度 o(n) to o(1)
const actions = {
'1': ['processing','IndexPage'],
'2': ['fail','FailPage'],
'3': ['fail','FailPage'],
'4': ['success','SuccessPage'],
'5': ['cancel','CancelPage'],
'default': ['other','Index'],
}
/**
* 按鈕點擊事件
* @param {number} status 活動狀態:1開團進行中 2開團失敗 3 商品售罄 4 開團成功 5 系統取消
*/
const onButtonClick = status => {
const action = actions[status] || actions['default']
const [logName, pageName] = action
sendLog(logName); jumpTo(pageName)
}
ES6 Map 寫法,且接受任何類型的作爲索引包括對象,.set(key, value)
const actions = new Map([
[1, ['processing','IndexPage']],
[2, ['fail','FailPage']],
[3, ['fail','FailPage']],
[4, ['success','SuccessPage']],
[5, ['cancel','CancelPage']],
['default', ['other','Index']]
])
/**
* 按鈕點擊事件
* @param {number} status 活動狀態:1 開團進行中 2 開團失敗 3 商品售罄 4 開團成功 5 系統取消
*/
const onButtonClick = (status)=>{
const action = actions.get(status) || actions.get('default')
sendLog(action[0]); jumpTo(action[1])
}
以對象作爲鍵,從而滿足複雜條件,可以設想以下業務場景,選購一件商品(紅色,xl,vip),以上條件滿足則執行下一步,ES5可以通過 'red|1|vip': function
作爲替代方案
const actions = new Map([
[{identity:'guest',status:1},()=>{/* functionA */}],
[{identity:'guest',status:2},()=>{/* functionA */}],
[{identity:'guest',status:3},()=>{/* functionA */}],
[{identity:'guest',status:4},()=>{/* functionA */}],
[{identity:'guest',status:5},()=>{/* functionB */}],
//...
])
再優化下,將處理邏輯函數進行緩存,將 status
進行二分法查找
const actions = ()=>{
const functionA = ()=>{/*do sth*/}
const functionB = ()=>{/*do sth*/}
return new Map([
[{identity:'guest',status:1},functionA],
[{identity:'guest',status:2},functionA],
[{identity:'guest',status:3},functionA],
[{identity:'guest',status:4},functionB],
[{identity:'guest',status:5},functionB],
//...
])
}
const onButtonClick = (identity,status)=>{
const action = [...actions()].filter(([key,value])=>(key.identity == identity && key.status == status))
action.forEach(([key,value])=>value.call(this))
}
或者通過正則作爲判斷條件,利用數組循環的特性,符合正則條件的邏輯都會被執行,那就可以同時執行公共邏輯和單獨邏輯
[/^guest_[1-4]$/, functionA],
[/^guest_5$/, functionB],
[/^guest_.*$/, functionC],
解構賦值
剔除對象或對象不需要的屬性的值,解構套娃和重命名的用法自行百度…
const obj = {
name: 'detanx',
age: 24,
height: 180
}
// 剔除height
const { height, ...otherObj } = obj;
// otherObj => {name: 'detanx', age: 24}
利用參數默認值的特性,引用解構賦值的其他變量
let [x = 1, y = x] = [2]; // => x=2; y=2