前言
本文開始針對項目中總結出來的關於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))
更多
以上方法只是根據個人經驗和想法進行的一些可優化的思維拓展,有些可能是矯枉過正,但代碼的優化道路上,從來都是要特定場景下解決特定需求的,爲的還是要讓使用更簡單,讓使用者更習慣、高效的開發,提前或者滯後的將代碼進行優化重構固然都是錯的,但如果一點點優化的思考和什麼程度應該去做重構了不去探索就進步太慢了。