很多工具函数大家都知道,比如防抖函数,节流函数,深拷贝函数等,一问都会,一写就废,用lodash的掘友们,是不是基本功都退化了?CV工程师请不要把基本功给弄丢了,下面我来整理一下项目中常用的工具函数,多练练吧,不然面试现场写不出来多丢人啊!文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16885.html
1.防抖函数
js
复制代码
/**
* 防抖函数,最后一次调用,至少等待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.节流函数
js
复制代码
/**
* 节流函数,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.深拷贝函数
js
复制代码
/**
* 深拷贝函数
* @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.对象中删除某个数,并返回新的对象
js
复制代码
/**
* 实现从无限嵌套对象或者数组中删除某个数,并返回新的对象
* @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.请求队列设置最大请求数
js
复制代码
/**
* 控制并发请求,所有的请求放到请求队列中,当请求数量大于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.订阅消息函数,包括订阅消息、发布消息和取消订阅的功能
js
复制代码
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
方法的示例:文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16885.html
javascript
复制代码
/**
* 从对象中获取嵌套属性的值,如果属性不存在,则返回默认值。
* @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
文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16885.html文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16885.html
评论