前端-JavaScript深浅拷贝

107 阅读1分钟

一、基本类型和引用类型

  • 基本类型:包括stringnumberbooleanundefinednullsymbolbigint,这些类型的值是直接存储在栈中的。

  • 引用类型:包括objectarrayfunction等,这些类型的值是引用类型。值存储在堆中,栈中存储的是指向堆内存的引用。

二、浅拷贝

1、基本数据类型

  • 直接复制值,新旧变量相互独立互不影响。

2、引用数据类型

  • 只是复制了对象的引用,因此两个变量指向同一个内存地址,修改其中一个会影响到另一个。

浅拷贝.png

3、常用方法

// 缺点:无法拷贝嵌套对象
const copy = Object.assign({}, source);
// 缺点:无法拷贝嵌套对象
const copy = { ...source };
// 缺点:只能拷贝对象的属性,不能拷贝对象的方法
const copy = JSON.parse(JSON.stringify(obj));

三、深拷贝

1、基本数据类型

  • 直接复制值,新旧变量相互独立互不影响。

2、引用数据类型

  • 深拷贝会在堆中开辟新内存地址,创建一个完全独立的新对象。无论多深的嵌套,拷贝后新对象的任何修改都不会影响原对象。

深拷贝.png

3、常用方法

function deepClone(obj, cache = new Map()) {
    // 如果对象是 null 或者已经是基本数据类型了,直接返回
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }
    // 如果缓存中已经有了,直接返回
    if (cache.has(obj)) {
        return cache.get(obj);
    }
    // 创建一个新的对象或数组
    const result = Array.isArray(obj) ? [] : {};
    // 缓存中没有,写入缓存
    cache.set(obj, result);
    // 遍历对象的所有属性
    for (let key in obj) {
        // 确保属性是对象自身的属性,而不是原型链上的
        if (obj.hasOwnProperty(key)) {
            // 递归拷贝属性值
            result[key] = deepClone(obj[key], cache);
        }
    }
    return result;
}