lodash手写源码-cloneDeep,debounce,throttle

一、源码地址

二、函数介绍

_.cloneDeep - 深拷贝对象

用于创建一个对象或数组的深拷贝,即递归地复制对象及其所有嵌套的属性,新对象与原对象在内存中是完全独立的。

浅拷贝

浅拷贝创建一个新对象,新对象的属性会直接复制原对象的属性。但对于引用类型的属性,浅拷贝仅仅复制其引用,而不是复制实际的对象。这意味着新对象和原对象中的引用类型属性会指向同一个内存地址,修改其中一个对象的引用类型属性会影响到另一个对象。

  • 使用 Object.assign():用于将一个或多个源对象的所有可枚举属性复制到目标对象。
javascript 复制代码
const original = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, original);

// 修改浅拷贝对象的引用类型属性
shallowCopy.b.c = 3;

console.log(original.b.c); // 输出: 3,说明原对象也被修改了
  • 使用扩展运算符:是一种更简洁的对象复制方式。
javascript 复制代码
const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };

shallowCopy.b.c = 3;
console.log(original.b.c); // 输出: 3
深拷贝

深拷贝同样创建一个新对象,并且会递归地复制原对象的所有属性,包括嵌套的引用类型属性。这会在内存中创建一个完全独立的对象,新对象和原对象在内存中没有共享的部分,修改新对象不会影响原对象。

  • 使用 JSON.parse(JSON.stringify()):这种方法简单直接,但有局限性,比如不能处理函数、正则表达式等特殊对象。
javascript 复制代码
const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.b.c = 3;
console.log(original.b.c); // 输出: 2,原对象未被修改
  • 手写递归函数:可以处理各种类型的对象,但实现相对复杂。

_.debounce - 防抖函数

防抖函数用于限制一个函数在一定时间内只能被调用一次。当持续触发事件时,在规定时间内没有再次触发事件,函数才会执行;如果在规定时间内再次触发事件,则重新计时。

_.throttle - 节流函数

节流函数用于限制一个函数在一定时间内只能被调用一次。当持续触发事件时,在规定时间内,函数只会执行一次,之后在这个时间间隔内再次触发事件,函数不会执行。

三、手写代码

_.cloneDeep

javascript 复制代码
function cloneDeep(obj) {
    if (typeof obj!== 'object' || obj === null) {
        return obj;
    }

    let clone = Array.isArray(obj)? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = cloneDeep(obj[key]);
        }
    }
    return clone;
}

// 测试
const original = { a: 1, b: { c: 2 } };
const cloned = cloneDeep(original);
console.log(cloned); 

_.debounce

javascript 复制代码
function debounce(func, delay) {
    let timer = null;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

// 测试
function myFunction() {
    console.log('Function called');
}

const debouncedFunction = debounce(myFunction, 1000);
debouncedFunction(); 
debouncedFunction(); 

_.throttle

javascript 复制代码
function throttle(func, delay) {
    // 记录上一次执行函数的时间,初始值为 0
    let lastTime = 0;

    // 返回一个新的函数,这个新函数就是节流后的函数
    return function() {
        // 获取当前的时间戳
        const now = Date.now();
        // 如果当前时间与上一次执行时间的差值大于等于设定的延迟时间
        if (now - lastTime >= delay) {
            // 调用传入的原始函数,并使用 apply 方法绑定正确的 this 值和参数
            func.apply(this, arguments);
            // 更新上一次执行函数的时间为当前时间
            lastTime = now;
        }
    };
}

// 示例使用
function sayHello() {
    console.log('Hello!');
}

// 创建一个节流后的函数,每 2000 毫秒(2 秒)执行一次
const throttledSayHello = throttle(sayHello, 2000);

// 模拟频繁调用
setInterval(throttledSayHello, 200);
相关推荐
石像鬼₧魂石4 小时前
SET的钓鱼网站钓鱼模块
windows·学习·ubuntu
Gavin在路上4 小时前
AI学习之稀疏 MoE+Transformer架构
人工智能·学习·transformer
d111111111d4 小时前
C语言中,malloc和free是什么,在STM32中使用限制是什么,该如何使用?
c语言·开发语言·笔记·stm32·单片机·嵌入式硬件·学习
【ql君】qlexcel4 小时前
DDR学习笔记1
学习·ddr
d111111111d5 小时前
STM32 平衡车前置:直流电机正反转 PID 控制(编码器测速 + PWM 驱动)
笔记·stm32·单片机·嵌入式硬件·学习
学工科的皮皮志^_^5 小时前
光模块学习
经验分享·笔记·嵌入式硬件·学习
少年、潜行5 小时前
F1C100/200S学习笔记(3)-- 裸机开发
linux·笔记·学习·驱动·裸机·f1c200s
老王熬夜敲代码5 小时前
网路编程--协议
linux·网络·笔记
芥子沫5 小时前
Docker安装Blossom笔记
笔记·docker·容器
UVM_ERROR5 小时前
Git仓库损坏(Segmentation fault)修复实战:虚拟机环境下UVM项目救援指南
笔记·git·vscode·github·芯片