這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 代碼的簡潔、美感、可讀性等等也許不影響程式的執行,但是卻對人(開發者)的影響非常之大,甚至可以說是影響開發者幸福感的重要因素之一; 瞭解一些有美感的代碼,不僅可以在一定程度上提高程式員們的開發效率,有些還能提高代碼的性能,可謂是一舉 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
前言
- 代碼的簡潔、美感、可讀性等等也許不影響程式的執行,但是卻對人(開發者)的影響非常之大,甚至可以說是影響開發者幸福感的重要因素之一;
- 瞭解一些有美感的代碼,不僅可以在一定程度上提高程式員們的開發效率,有些還能提高代碼的性能,可謂是一舉多得;
筆者至今難以忘記最開始踏入程式員領域時接觸的一段List
內嵌for
的Python代碼:
array = [[16, 3, 7], [2, 24, 9], [4, 1, 12]] row_min = [min(row) for row in array ] print(row_min)
這可能就是動態語言非常優秀的一點,而JavaScript同樣作為動態語言,其中包含的優秀代碼片段也非常之多,比如我們通過JavaScript也可以非常輕鬆地實現上述的功能:
const array = [[16, 3, 7], [2, 24, 9], [4, 1, 12]] const row_min = array.map(item => Math.min(...item)) console.log(row_min)
能寫出優秀的代碼一直是筆者所追求的,以下為筆者在開發閱讀過程積累的一些代碼片段以及收集了互聯網上一些優秀代碼片段,希望對你有所幫助
概述
這裡,考慮到有些技巧是大家見過的或者說是已經爛熟於心的,但總歸有可能有些技巧沒有留意過,為了讓大家更加清楚的找到自己想要查閱的內容以查漏補缺,所以這裡筆者貼心地為大家提供了一張本文內容的索引表,供大家翻閱以快速定位,如下:
應用場景標題 | 描述 | 補充1 | 補充2 |
---|---|---|---|
數組去重 | 略 | 通過內置數據解構特性進行去重[] => set => [] |
通過遍歷並判斷是否存在進行去重[many items].forEach(item => (item <不存在於> uniqueArr) && uniqueArr.push(item)) |
數組的最後一個元素 | 獲取數組中位置最後的一個元素 | 使用at(-1) |
略 |
數組對象的相關轉換 | 略 | 對象到數組:Object.entries() |
數組到對象:Obecjt.fromEntries() |
短路操作 | 通過短路操作避免後續表達式的執行 | a或b :a真b不執行 |
a且b :a假b不執行 |
基於預設值的對象賦值 | 通過對象解構合併進行帶有預設值的對象賦值操作 | {...defaultData, ...data} |
略 |
多重條件判斷優化 | 單個值與多個值進行對比判斷時,使用includes 進行優化 |
[404,400,403].includes |
略 |
交換兩個值 | 通過對象解構操作進行簡潔的雙值交換 | [a, b] = [b, a] | 略 |
位運算 | 通過位運算提高性能和簡潔程度 | 略 | 略 |
replace() 的回調 |
通過傳入回調進行更加細粒度的操作 | 略 | 略 |
sort() 的回調 |
通過傳入回調進行更加細粒度的操作 | 根據字母順序排序 | 根據真假值進行排序 |
數組去重
這不僅是我們平常編寫代碼時經常會遇到的一個功能實現之一,也是許多面試官在考查JavaScript基礎時喜歡考查的題目,比較常見的基本有如下兩類方法:
1)通過內置數據結構自身特性進行去重
主要就是利用JavaScript內置的一些數據結構帶有不包含重覆值的特性,然後通過兩次數據結構轉換的消耗[] => set => []
從而達到去重的效果,如下演示:
const arr = ['justin1go', 'justin2go', 'justin2go', 'justin3go', 'justin3go', 'justin3go']; const uniqueArr = Array.from(new Set(arr)); // const uniqueArr = [...new Set(arr)];
2)通過遍歷並判斷是否存在進行去重
白話描述就是:通過遍歷每一項元素加入新數組,新數組存在相同的元素則放棄加入,偽代碼:[many items].forEach(item => (item <不存在於> uniqueArr) && uniqueArr.push(item))
至於上述的<不存在於>
操作,可以是各種各樣的方法,比如再開一個for
迴圈判斷新數組是否有相等的,或者說利用一些數組方法判斷,如indexOf、includes、filter、reduce等等
const arr = ['justin1go', 'justin2go', 'justin2go', 'justin3go', 'justin3go', 'justin3go']; const uniqueArr = []; arr.forEach(item => { // 或者!uniqueArr.includes(item) if(uniqueArr.indexOf(item) === -1){ uniqueArr.push(item) } })
結合filter()
,判斷正在遍歷的項的index,是否是原始數組的第一個索引:
const arr = ['justin1go', 'justin2go', 'justin2go', 'justin3go', 'justin3go', 'justin3go']; const uniqueArr = arr.filter((item, index) => { return arr.indexOf(item, 0) === index; })
結合reduce()
,prev初始設為[]
,然後依次判斷cur
是否存在於prev
數組,如果存在則加入,不存在則不動:
const arr = ['justin1go', 'justin2go', 'justin2go', 'justin3go', 'justin3go', 'justin3go']; const uniqueArr = arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
數組的最後一個元素
對於獲取數組的最後一個元素,可能平常見得多的就是arr[arr.length - 1]
,我們其實可以使用at()
方法進行獲取
const arr = ['justin1go', 'justin2go', 'justin3go']; console.log(arr.at(-1)) // 倒數第一個值 console.log(arr.at(-2)) // 倒數第二個值 console.log(arr.at(0)) // 正數第一個 console.log(arr.at(1)) // 正數第二個
註:node14應該是不支持的,目前筆者並不建議使用該方法,但獲取數組最後一個元素是很常用的,就應該像上述語法一樣簡單...
數組對象的相互轉換
- 相信大家比較熟悉的是從對象轉換為數組的幾種方法如:
Object.keys()
、Object.values()
、Object.entries
; - 但其實還可以通過
Object.fromEntries()
將一個特定數組轉換回對象:
const entryified = [ ["key1", "justin1go"], ["key2", "justin2go"], ["key3", "justin3go"] ]; const originalObject = Object.fromEntries(entryified); console.log(originalObject);
短路操作
被合理運用的短路操作不僅非常的優雅,還能減少不必要的計算操作
1)基本介紹
主要就是||
或操作、&&
且操作當第一個條件(左邊那個)已經能完全決定整個表達式的值的時候,編譯器就會跳過該表達式後續的計算
- 或操作
a || b
:該操作只要有一個條件為真值時,整個表達式就為真;即a
為真時,b
不執行; - 且操作
a && b
:該操作只要有一個條件為假值時,整個表達式就為假;即a
為假時,b
不執行;
2)實例
網路傳輸一直是前端的性能瓶頸,所以我們在做一些判斷的時候,可以通過短路操作減少請求次數:
const nextStep = isSkip || await getSecendCondition(); if(nextStep) { openModal(); }
還有一個經典的代碼片段:
function fn(callback) { // some logic callback && callback() }
基於預設值的對象賦值
- 很多時候,我們在封裝一些函數或者類時,會有一些配置參數。
- 但這些配置參數通常來說會給出一個預設值,而這些配置參數用戶是可以自定義的
- 除此之外,還有許許多多的場景會用到的這個功能:基於預設值的對象賦值。
function fn(setupData) { const defaultSetup = { email: "[email protected]", userId: "justin3go", skill: "code", work: "student" } return { ...defaultSetup, ...setupData } } const testSetData = { skill: "sing" } console.log(fn(testSetData))
如上{ ...defaultSetup, ...setupData }
就是後續的值會覆蓋前面key
值相同的值。
多重條件判斷優化
if(condtion === "justin1go" || condition === "justin2go" || condition === "justin3go"){ // some logic }
如上,當我們對同一個值需要對比不同值的時候,我們完全可以使用如下的編碼方式簡化寫法並降低耦合性:
const someConditions = ["justin1go", "justin2go", "justin3go"]; if(someConditions.includes(condition)) { // some logic }
交換兩個值
一般來說,我們可以增加一個臨時變數來達到交換值的操作,在Python中是可以直接交換值的:
a = 1 b = 2 a, b = b, a
而在JS中,也可以通過解構操作交換值;
let a = 1; let b = 2; [a, b] = [b, a]
簡單理解一下:
- 這裡相當於使用了一個數組對象同時存儲了a和b,該數組對象作為了臨時變數
- 之後再將該數組對象通過解構操作賦值給a和b變數即可
同時,還有種比較常見的操作就是交換數組中兩個位置的值:
const arr = ["justin1go", "justin2go", "justin3go"]; [arr[0], arr[2]] = [arr[2], arr[0]]
位運算
關於位運算網上的討論參差不齊,有人說位運算性能好,簡潔;也有人說位運算太過晦澀難懂,不夠易讀,這裡筆者不發表意見,僅僅想說的是儘量在使用位運算代碼的時候寫好註釋!
下麵為一些常見的位運算操作,參考鏈接
1 ) 使用&運算符判斷一個數的奇偶
// 偶數 & 1 = 0 // 奇數 & 1 = 1 console.log(2 & 1) // 0 console.log(3 & 1) // 1
2 ) 使用~, >>, <<, >>>, |
來取整
console.log(~~ 6.83) // 6 console.log(6.83 >> 0) // 6 console.log(6.83 << 0) // 6 console.log(6.83 | 0) // 6 // >>>不可對負數取整 console.log(6.83 >>> 0) // 6
3 ) 使用^
來完成值交換
var a = 5 var b = 8 a ^= b b ^= a a ^= b console.log(a) // 8 console.log(b) // 5
4 ) 使用&, >>, |
來完成rgb值和16進位顏色值之間的轉換
/** * 16進位顏色值轉RGB * @param {String} hex 16進位顏色字元串 * @return {String} RGB顏色字元串 */ function hexToRGB(hex) { var hexx = hex.replace('#', '0x') var r = hexx >> 16 var g = hexx >> 8 & 0xff var b = hexx & 0xff return `rgb(${r}, ${g}, ${b})` } /** * RGB顏色轉16進位顏色 * @param {String} rgb RGB進位顏色字元串 * @return {String} 16進位顏色字元串 */ function RGBToHex(rgb) { var rgbArr = rgb.split(/[^\d]+/) var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3] return '#'+ color.toString(16) } // ------------------------------------------------- hexToRGB('#ffffff') // 'rgb(255,255,255)' RGBToHex('rgb(255,255,255)') // '#ffffff'
replace()
的回調函數
之前寫過一篇文章介紹了它,這裡就不重覆介紹了,F=>傳送
sort()
的回調函數
sort()
通過回調函數返回的正負情況來定義排序規則,由此,對於一些不同類型的數組,我們可以自定義一些排序規則以達到我們的目的:
- 數字升序:
arr.sort((a,b)=>a-b)
- 按字母順序對字元串數組進行排序:
arr.sort((a, b) => a.localeCompare(b))
- 根據真假值進行排序:
const users = [ { "name": "john", "subscribed": false }, { "name": "jane", "subscribed": true }, { "name": "jean", "subscribed": false }, { "name": "george", "subscribed": true }, { "name": "jelly", "subscribed": true }, { "name": "john", "subscribed": false } ]; const subscribedUsersFirst = users.sort((a, b) => Number(b.subscribed) - Number(a.subscribed))