作者 | Before Semicolon

譯者 | 王強

策劃 | 李俊辰

寫代碼的時候總有一些東西是會重複出現的,次數多了你就會想找找捷徑了。這類問題中有很大一部分解決起來甚至連庫都不用裝。下面就是我多年來收集的前 25 個捷徑和小技巧。

1. 類型檢查小工具

Java 不是強類型語言,對此我推薦的最佳解決方案是 Type。但有時你只是想要一個簡單的類型檢查,這種時候 Java 允許你使用“typeof”關鍵字。

“typeof”的問題在於,將其用於某些原語和函數時效果很好,但對於數組和對象來說,由於它們都被視爲“對象”,因此很難把握它們之間的區別。

// check for null typetype.null= x => x === null;// check for undefined typetype.undefined= x => x === undefined;// check for nil type. Either null or undefinedtype.nil = x => type.null(x) || type.undefined(x);// check for strings and string literal type. e.g: 's', "s", `str`, new Stringtype.string= x => !type.nil(x) && (typeofx === 'string' || x instanceofString);// check for number or number literal type. e.g: 12, 30.5, new Numbertype.number= x => !type.nil(x)&& (// NaN & Infinity have typeof "number" and this excludes that(!isNaN(x) && isFinite(x)&& typeofx === 'number') || x instanceofNumber);// check for boolean or boolean literal type. e.g: true, false, new Booleantype.boolean= x => !type.nil(x) && (typeofx === 'boolean' || x instanceofBoolean);// check for array typetype.array = x => !type.nil(x) && Array.isArray(x);// check for object or object literal type. e.g: {}, new Object, Object.create(null)type.object = x => ({}).toString.call(x) === '[object Object]';// check for provided type instancetype.type= (x, X) => !type.nil(x) && x instanceofX;// check for set typetype.set= x => type.type(x, Set);// check for map typetype.map = x => type.type(x, Map);// check for date typetype.date = x => type.type(x, Date);

returntype;});

2. 檢查是否爲空

有時你需要知道某些內容是否爲空,並根據結果決定要使用的方法,例如檢查長度、大小或是否包含任何子元素。下面這個工具打包了這些功能,你可以用它檢查 String、Object、Array、Map 和 Set 的大小。

if(x instanceofMap|| x instanceofSet) {returnx.size === 0;}

if(({}).toString.call(x) === '[object Object]') {returnObject.keys(x).length === 0;}

returnfalse;}

3. 獲取列表最後一項

其他語言裏這個功能被做成了可以在數組上調用的方法或函數,但在 Java 裏面,你得自己做點工作。

if(listinstanceofSet) {returnArray.from(list).slice(-1)[0];}

if(listinstanceofMap) {returnArray.from(list.values).slice(-1)[0];}}

4. 帶有範圍的隨機數生成器

有時你需要生成隨機數,但希望這些數字在一定範圍內,那就可以用這個工具。

returnMath.floor(Math.random * (max- min) + min);}

5. 隨機 ID 生成器

有時你只是需要一些 ID?除非你要的是更復雜的 ID 生成器(例如 UUID),否則用不着爲此安裝什麼新庫,下面這個選項足夠了。你可以從當前時間(以毫秒爲單位)或特定的整數和增量開始生成,也可以從字母生成 ID。

while(true)yieldmil += 1;})();

return() => id.next().value;});// createuniqueincrementingidstartingfromprovidedvalueorzero// goodfortemporarythingsorthingsthatidresetsconstuniqueIncrementingId= ((lastId = 0) => {constid = (function*() {letnumb = lastId;

while(true)yieldnumb += 1;})()

return(length = 12) => `${id.next().value}`.padStart(length, '0');});// createuniqueidfromlettersandnumbersconstuniqueAlphaNumericId= (() => {constheyStack = '0123456789abcdefghijklmnopqrstuvwxyz';constrandomInt = () => Math.floor(Math.random() * Math.floor(heyStack.length))

return(length = 24) => Array.from({length}, () => heyStack[randomInt()]).join('');});

6. 創建一個範圍內的數字

Python 裏我很喜歡的一個功能是 range 函數,而在 Java 裏我經常需要自己寫這個功能。下面是一個簡單的實現,非常適合 for…of 循環以及需要特定範圍內數字的情況。

if(end <= maxOrStart) {return[];}

if(step !== null) {returnArray.from({length: Math.ceil(((end - maxOrStart) / step))},(_, i) =>(i * step) + maxOrStart);}

returnArray.from({length: Math.ceil((end - maxOrStart))},(_, i) =>i + maxOrStart);}

7. 格式化 JSON 字符串,stringify 任何內容

我在使用 NodeJs 將對象記錄到控制檯時經常使用這種方法。JSON.stringify 方法需要第三個參數,該參數必須有多個空格以縮進行。第二個參數可以爲 null,但你可以用它來處理 function、Set、Map、Symbol 之類 JSON.stringify 方法無法處理或完全忽略的內容。

return(obj, spaces = 0) => JSON.stringify(obj, replacer, spaces)});

8. 順序執行 promise

如果你有一堆異步或普通函數都返回 promise,要求你一個接一個地執行,這個工具就會很有用。它會獲取函數或 promise 列表,並使用數組 reduce 方法按順序解析它們。

if(typeofx === 'function') {// if function is not async this will turn its result into a promise// if it is async this will await for the resultreturn(async() => awaitx())();}

returnPromise.resolve(x)}

return(list) => {constresults = [];

returnlist.reduce((lastPromise, currentPromise) => {returnlastPromise.then(res => {results.push(res); // collect the resultsreturntoPromise(currentPromise);});}, toPromise(list.shift()))// collect the final result and return the array of results as resolved promise.then(res => Promise.resolve([...results, res]));}});

9. 輪詢數據

‍如果你需要持續檢查數據更新,但系統中沒有 WebSocket,則可以使用這個工具來執行操作。它非常適合上傳文件時,想要持續檢查文件是否已完成處理的情況,或者使用第三方 API(例如 dropbox 或 uber)並且想要持續檢查過程是否完成或騎手是否到達目的地的情況。

10. 等待所有 promise 完成

這個算不上是代碼解決方案,更多是對 Promise API 的強化。這個 API 在不斷進化,以前我還爲“allSettled”“race”和“any”做了代碼實現,現在直接用 API 的就好了。

11. 交換數組值的位置

ES6 開始,從數組中的不同位置交換值變得容易多了。這個做起來不難,但是瞭解一下也不錯,

12. 條件對象鍵

我最喜歡這條技巧了,我在使用 React 更新狀態時經常用它。你可以將條件包裝在括號中來有條件地將一個鍵插入一個 spread 對象。

13. 使用變量作爲對象鍵

當你有一個字符串變量,並想將其用作對象中的鍵以設置一個值時可以用它。

14. 檢查對象裏的鍵

這是一個很好的技巧,可以幫助你檢查對象鍵。

15. 刪除數組重複項

數組中經常有重複的值,你可以使用 Set 數據結構來消除它。它適用於許多數據類型,並且 set 有多種檢查相等性的方法,很好用。對於不同實例或對象的情況,你還是可以使用 Set 來跟蹤特定事物並過濾出重複的對象。

16. 在 ArrayforEach 中執行“break”和“continue”

我真的很喜歡使用數組“.forEach”方法,但有時我需要提早退出或繼續進行下一個循環,而不想用 for...loop。你可以複製“continue”語句行爲來提前返回,但如果要複製“break”行爲,則需要使用數組“.some”方法。

17. 使用別名和默認值來銷燬

Destructuring(銷燬)是 Java 最好用的功能之一,而且你可以使用“冒號”設置別名,並使用“等號”設置屬性默認值。

18. 可選鏈和空值合併

深入檢查對象屬性並處理 null 和 undefined 值時,你可以使用幾個非常好用的 Java 功能來解決常見的問題。

19. 用函數擴展類

我經常對別人講,Java 類只是構造函數和底層的原型,不是像 Java 中那樣的真實概念。一個證據是,你可以只使用一個構造函數來擴展一個類。在私有內容裏這個很好用,在類裏“#”這些看着很奇怪,並且用於 babel 或 WebPack 時,編譯出來的代碼更少。

20. 擴展構造函數

類的一個問題是你只能擴展一個其他類。使用構造函數,你可以使用多個構造函數來構成一個函數,這樣就會靈活多了。你可以使用函數原型的.apply 或.call 方法來實現。你甚至可以只擴展函數的一部分,只要它是一個對象即可。

21. 循環任何內容

有時,你需要循環任何可迭代的內容(Set、Map、Object、Array、String 等)。這個非常簡單的 forEach 函數工具就可以做到這一點。如果回調返回 true,它將退出循環。

for(;i < len; i++) {constres = callback(entries[i][1], entries[i][0], list);

if(res === true) break;}}

22. 使函數參數爲 required

這是一種確保函數調用了完成工作所需內容的絕佳方法。你可以使用默認參數值的特性來調用函數,然後就會拋出一個錯誤。如果調用該函數時帶上了它需要的值,則該值將替換該函數,並且什麼也不會發生。使用 undefined 調用也有相同的效果。

23. 創建模塊或單例

很多時候,你需要在加載時初始化某些內容,設置它需要的各種事物,然後就可以在應用程序中到處使用它,而無需再做什麼補充工作。你可以使用 IIFE 函數來做到這一點,這個函數太好用了。這種模塊模式用來隔離事物非常好用,它可以只暴露需要交互的內容。

24. 深度克隆對象

開發人員通常會安裝一些類似“lodash”的庫來執行這一操作,但使用純 Java 來實現確實也很容易。這是一個簡單的遞歸函數:只要是一個對象,就使用函數的構造器將其重新初始化爲一個克隆,然後對所有屬性重複該過程。

Object.getOwnPropertyNames(obj).forEach(prop=>(clone[prop] = deepClone(obj[prop])));}returnclone;};

25. 深度凍結對象

如果你喜歡不變性,那麼這個工具你一定要常備。

Object.getOwnPropertyNames(obj).forEach(prop=>(clone[prop] = deepClone(obj[prop])));}returnclone;};

中國三大電信運營商被迫從美股退市,商務部:將採取必要措施

2020年,不可錯過的技術圈十大“翻車”事件

我真的逃不掉拼多多真香定律

InfoQ 讀者交流羣上線啦!各位小夥伴可以掃描下方二維碼,添加 InfoQ 小助手,回覆關鍵字“進羣”申請入羣。回覆“資料”,獲取資料包傳送門,註冊 InfoQ 網站後,可以任意領取一門極客時間課程,免費滴!大家可以和 InfoQ 讀者一起暢所欲言,和編輯們零距離接觸,超值的技術禮包等你領取,還有超值活動等你參加,快來加入我們吧!

點個在看少個 bug👇

點個在看少個 bug👇

相關文章