前言
本文開始針對專案中總結出來的關於js基礎知識的程式碼優化技巧進行每個細節點的分析,後續還會針對某個專題的分析。
案例說明
if針對同一關鍵值多條件的判斷
針對key進行多條件判斷,而其中的多條件可能有些可以歸為一類,因為其執行的程式碼是相同的
//優化前
if(key === 1 || key ===3 || key===9){
//some codes here
}
//優化後
let codesOptionArr = [1,3,9]
if(codesOptionArr.includes(key)){
//some codes here
}
複製程式碼
針對多case,分別返回或者設定不同值,程式碼段很簡單
需要根據不同的值情況,來返回或者設定對應的值,相信很多人會說用switch來進行優化,其實用物件字面量會更好,也更方便維護和複用。比較常見的是前端常見的一些列舉資料以及固定值。
//優化前
let str =''
switch(type){
case 'name': str ='姓名'
break
case 'sex': str ='性別'
break
}
//優化後
function getTypeStr (type){
if(!type) return ''
let dict = {
name:'姓名',
sex:'性別'
}
return dict[type] || type
}
let str = getTypeStr(type)
複製程式碼
少寫巢狀,儘早返回
缺點除了邏輯分不清楚,還會導致程式碼執行效能低,在執行完需要的邏輯之後不能跳出方法。所以建議針對已經符合返回的情況下 ,就返回對應的邏輯,不再進行多餘的判斷。
//優化前
function judgeAge(age){
let str =''
if(age && !isNaN(age) && age> 0 ){
if(age <18) {
str = '還是未成年 '
} else {
str = '符合要求'
}
} else {
str = '年齡不合法'
}
return str
}
//優化後
function judgeAge(age){
if(!age || isNaN(age) || age < 0 ){
return '年齡不合法'
}
if(age<18) return '還是未成年'
else{
return '符合要求'
}
}
複製程式碼
方法內的返回或者對應關係具有關聯關係,或者可以進行一定的程式碼關聯設計,這裡不針對物件字面量。
//優化前
let str =''
switch(number) {
case 0 : str = '沒有任何收入'
break
case 1 :str='您有一枚硬幣了'
break
}
return str
//優化後
let descArr = ['沒有任何收入','您有一枚硬幣了']
return descArr[number]
複製程式碼
使用函式預設值和解構
也許你之前沒有用過函式預設值,也沒有分析過解構能帶來什麼優化。
// 優化前
function fn(age){
let _age = age || 0
console.log(_age)
}
// 優化後
function fn(age = 0){
console.log(age)
}
// 優化前
function fn(person){
if(person && person.name) {
console.log(pserson.name || '')
}
}
// 優化後
function fn({name}){
console.log(name || '')
}
複製程式碼
合併條件與執行語句
在庫程式碼中經常看到一些判斷條件與執行語句、返回語句寫在一起,非常簡潔高效,也可讀性較高。
let getArrlen= (str,arr) => {
if(!(arr instanceof(Array))) return 'arr is not arr '
return arr && arr.length
}
複製程式碼
批量物件屬性賦值
使用場景:主要是針對需要把物件的一些屬性批量的賦值到另外一個物件上,然後如果你的屬性很多可能要寫很多賦值語句。(前提是屬性名一般是相同的)
說明:可能有人會問為什麼不直接用這個物件,答案也很簡單,如果可以直接用,當然直接用是最好的,我自己在寫介面param的時候,就會注意這些,需要傳參的部分封裝到一個特殊的物件裡,然後進行data的繫結,這樣需要的時候直接用傳參物件。但這裡討論的不是這種情況。
//優化前
let data = {}
data.name = this.form.name
data.len = this.form.len
data.amount = this.form.amount
//優化版本一 :利用物件的解構
let {name,len,amount} = this.form
//利用物件解構還可以支援屬性名變更的情況
let {name,len:length,amount:money} = this.form
let data = {name,len,amount}
// 優化後
let data = this.setProps[{source:this.form,propArr:['name','len','amount']}]
//優化版本二 :可以支援批量的匯入需要賦值的,對於拷貝物件,用source屬性承接,而需要賦值的屬性用propArr承接
//在方法中用json的相關方法支援了簡單的物件深拷貝
// 批量載入物件屬性,支援傳入陣列[{source:sourceObj,propArr:[]}]
setProps(arr) {
if (arr.length <= 0) return {}
return arr.reduce((acc, item) => {
item.propArr.reduce((acc, prop) => {
if (typeof item.source[prop] === 'object') {
acc[prop] = JSON.parse(JSON.stringify(item.source[prop]))
} else {
acc[prop] = item.source[prop]
}
return acc
}, acc)
return acc
}, {})
}
複製程式碼
擴充思考:像這種程式碼如果你的vue程式碼裡經常寫,不妨在你的mixins中混入這個方法,可以為你的頁面節省大量的程式碼空間。
批量變數重置
在我們的程式碼中經常會遇到吧一些變數進行重置,這部分程式碼重複率很高又沒有技術含量,所以我寫一個工具方法進行簡單的支援,程式碼優化。
//優化前
this.search = false
this.data = []
this.cur_page = 1
this.pageNo = 1
this.totalCount = 0
this.processType = ''
this.person = ''
this.keyword = ''
this.taskStatus = ''
this.stdate = []
this.processStatus = ''
// 優化後
this.resetVars([this.data,this.processType,this.person,this.keyword,this.taskStatus])
/**
* @author zhangbing
* @param [] arr 需要重置的陣列變數
* @param {*} options 配置物件 對於這裡的重置規則如果不符合需求的可以自定義option字典,然後用instanceof 判斷型別(todo)
*/
resetVars(arr, options) {
if (!arr || arr.length === 0) return
let _options = {
object: {},
string: '',
number: 0,
boolean: true,
null: null,
undefined: undefined
}
_options = options ? Object.assign({}, _options, options) : _options
return arr.map(item => {
if (_options.includes(typeof item)) {
item = _options[typeof item]
} else {
// 不存在重置型別的 重置為字串
item = ''
}
return item
})
}
複製程式碼
擴充思考:像這種程式碼如果你的vue程式碼裡經常寫,不妨在你的mixins中混入這個方法,可以為你的頁面節省大量的程式碼空間。
物件的淺拷貝與深拷貝
在js中,我們可以用等號來進行基本資料型別的賦值,而對於複雜資料型別也就是物件型別,其等號賦予的是物件地址,不能實現拷貝的目的。而我們知道的Object.assign實現的也是物件的淺拷貝。 所以一般情況下,如果你不確定的情況下,如果發現物件屬性值是物件型別,需要遞迴拷貝。核心知識點是:typeof source[prop] === 'object' ,return Object.assign(target[prop],source[prop]),直到物件屬性為基本型別.
這裡所講的不是這部分,而是利用JSON的轉化方法來實現簡單的物件深拷貝。當然這種方法是有弊端的,詳情參考我另一篇文章利用json序列化物件的問題
let target = JSON.parse(JSON.stringify(source))
複製程式碼
更多
以上方法只是根據個人經驗和想法進行的一些可優化的思維擴充,有些可能是矯枉過正,但程式碼的優化道路上,從來都是要特定場景下解決特定需求的,為的還是要讓使用更簡單,讓使用者更習慣、高效的開發,提前或者滯後的將程式碼進行優化重構固然都是錯的,但如果一點點優化的思考和什麼程度應該去做重構了不去探索就進步太慢了。