很多工具函式大家都知道,比如防抖函式,節流函式,深複製函式等,一問都會,一寫就廢,用lodash的各位前端們,是不是基本功都退化了?CV工程師請不要把基本功給弄丟了,下面我來整理一下專案中常用的工具函式,多練練吧,不然面試現場寫不出來多丟人啊!
1.防抖函式
/** * 防抖函式,最後一次呼叫,至少等待delay時間才執行,如果在delay時間內再次呼叫就重新計時。 * @param {*} func 傳入執行函式 * @param {*} delay 定義間隔時間 */ export const debounce = (func,delay)=>{ let timer; return function(...args){ clearTimeout(timer); timer = setTimeout(()=>{ func.apply(this,args); },delay) } }
2.節流函式
/** * 節流函式,fuc函式離上一次執行間隔delay才執行下一次,如果在delay時間內就重新計時,如果大於delay則更新最後一次的執行時間。 * @param {*} func 執行函式 * @param {*} delay 執行時間 */ export const throttle = (func,delay)=>{ let timer,last return function(...args){ let now = + new Date(); if(last && now < last + delay){ clearTimeout(timer); timer = setTimeout(()=>{ last = now; func.apply(this,args); },delay) }else{ last = now; func.apply(this,args); } } }
3.深複製函式
/** * 深複製函式 * @param {*} obj 引數 */ export const deeClone = (obj) => { //不是引用型別就不複製 if(!(obj instanceof Object)) return obj //如果形參obj是陣列,就建立陣列,如果是物件就建立物件 let objCopy = obj instanceof Array ? [] : {} for(let key in obj){ if(obj instanceof Object){ objCopy[key] = deepCopy(obj[key]) } else{ if(obj.hasOwnProperty(key)){ objCopy[key] = obj[key] } } } return objCopy }
4.物件中刪除某個數,並返回新的物件
/** * 實現從無限巢狀物件或者陣列中刪除某個數,並返回新的物件 * @param {*} object 物件 * @param {*} item 刪除的數 */ export const deleteItemFromObject = (obj , item)=>{ if(obj instanceof Object){ const objCopy = obj instanceof Array ? [] : {} for(let i in obj){ if(obj[i] instanceof Array ){ objCopy[i] = obj[i].filter( j=> j !== item).map(h => deleteItemFromObject(h, item)); }else{ objCopy[i] = deleteItemFromObject(obj[i],item) } } return objCopy }else{ return obj === item ? null : obj } }
5.請求佇列設定最大請求數
/** * 控制併發請求,所有的請求放到請求佇列中,當請求數量大於number時則在佇列中排隊等候,根據http1協議一次性最大請求數為6個 * @param {*} reqs 請求 * @param {*} number 請求佇列的數量 */ export const reqQueue = (reqs ,number)=>{ reqs = reqs || [] const requestQueue = (concurrency) => { concurrency = concurrency || 6 // 最大併發數 const queue = [] // 請求池 let current = 0 const dequeue = () => { while (current < concurrency && queue.length) { current++; const requestPromiseFactory = queue.shift() // 出列 requestPromiseFactory() .then(() => { // 成功的請求邏輯 }) .catch(error => { // 失敗 console.log(error) }) .finally(() => { current-- dequeue() }); } } return (requestPromiseFactory) => { queue.push(requestPromiseFactory) // 入隊 dequeue() } } const enqueue = requestQueue(6) for (let i = 0; i < reqs.length; i++) { enqueue(() => axios.get('/api/test' + i)) } }
6.訂閱訊息函式,包括訂閱訊息、釋出訊息和取消訂閱的功能
class EventEmitter { constructor() { this.events = {}; } // 訂閱訊息 subscribe(eventName, callback) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(callback); } // 取消訂閱 unsubscribe(eventName, callback) { if (!this.events[eventName]) { return; } this.events[eventName] = this.events[eventName].filter(cb => cb !== callback); } // 釋出訊息 publish(eventName, ...args) { if (!this.events[eventName]) { return; } this.events[eventName].forEach(callback => callback(...args)); } } // 示例用法 const emitter = new EventEmitter(); // 訂閱訊息 const callback1 = data => console.log('Callback 1:', data); const callback2 = data => console.log('Callback 2:', data); emitter.subscribe('message', callback1); emitter.subscribe('message', callback2); // 釋出訊息 emitter.publish('message', 'Hello, world!'); // 取消訂閱 emitter.unsubscribe('message', callback2); // 再次釋出訊息 emitter.publish('message', 'How are you?'); //列印輸出結果: //Callback 1: Hello, world! //Callback 2: Hello, world! //Callback 1: How are you?
實現 get
方法
以下是一個實現 lodash.get
方法的示例:
/** * 從物件中獲取巢狀屬性的值,如果屬性不存在,則返回預設值。 * @param {Object} object - 要查詢的物件 * @param {Array|string} path - 要獲取的屬性路徑 * @param {*} [defaultValue] - 如果解析值是 undefined ,這值會被返回 * @returns {*} - 返回解析的值 */ function get(object, path, defaultValue) { // 如果 path 是字串,使用 . 或 [ ] 分割成陣列 if (typeof path === 'string') { path = path.replace(/\[(\w+)\]/g, '.$1'); // 將 [key] 替換為 .key path = path.replace(/^\./, ''); // 去除開頭的 . path = path.split('.'); } // 使用陣列路徑進行遍歷 for (let i = 0; i < path.length; i++) { if (object == null) { // 如果物件為 null 或 undefined,返回預設值 return defaultValue; } object = object[path[i]]; } return object === undefined ? defaultValue : object; } // 示例 const obj = { a: { b: { c: 42, }, }, }; console.log(get(obj, 'a.b.c')); // 輸出: 42 console.log(get(obj, ['a', 'b', 'c'])); // 輸出: 42 console.log(get(obj, 'a.b.c.d', 'default')); // 輸出: default console.log(get(obj, 'a.b.c', 'default')); // 輸出: 42 console.log(get(obj, 'x.y.z', 'default')); // 輸出: default