很多工具函数大家都知道,比如防抖函数,节流函数,深拷贝函数等,一问都会,一写就废,用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