JavaScript 中常用的深拷贝-案例

JavaScript 中的“深拷贝”和“浅拷贝”都是指在对象和数组拷贝时,对于其内部的元素或属性的处理方式不同。

浅拷贝会复制对象的引用,而不是复制对象本身。这意味着当你更改副本对象中的属性时,原始对象的属性也会发生更改。常见的浅拷贝方法有:Object.assign()、扩展运算符(...)、Array.concat()等。

深拷贝则递归地复制了整个对象,包括其内部的元素或属性。这意味着当你更改副本对象中的属性时,原始对象的属性不会发生更改。常见的深拷贝方法有:JSON.parse(JSON.stringify())、 Lodash库的_.cloneDeep()等。

以下是一个浅拷贝的例子:

let originalObj = { name: 'Tom', age: 20 }
let copiedObj = Object.assign({}, originalObj)

copiedObj.name = 'Jerry'

console.log(originalObj) // { name: 'Tom', age: 20 }
console.log(copiedObj) // { name: 'Jerry', age: 20 }

以下是一个深拷贝的例子:

let originalObj = { name: 'Tom', age: 20, address: { city: 'Shanghai', country: 'China' } }
let copiedObj = JSON.parse(JSON.stringify(originalObj))

copiedObj.address.city = 'Beijing'

console.log(originalObj.address.city) // Shanghai
console.log(copiedObj.address.city) // Beijing

自定义方法一:

// 标准的深拷贝 => 引用数据类型(数组,对象)
function deepClone(source){
	//[]=>Array(基类)  {}=>Object
	const targetObj = source.constructor ===Array ? [] : {};
    for(let keys in source){
        if(source.hasOwnProperty(keys)){
            //keys => 3个类型 基础、引用(数组、对象)
            // 引用数据类型
            if(source[keys] && typeof source[keys] ==='object'){
                // 确定数据类型
                targetObj[keys] = source[keys].constructor === Array ? [] : {};
                // 递归
                targetObj[keys] = deepClone(source[keys]);
            }else{
                // 基础数据类型
                targetObj[keys] = source[keys];
            }
        }
    }
    return targetObj;
}

 使用:

let newArray={
    a:1,
    b:'3',
    c:{u:'1',f:2},
    d:[1,'2',3]
}

console.log('原始:',newArray);

// JSON方式拷贝
let newArray2 = JSON.parse(JSON.stringify(newArray))
console.log('JSON方式拷贝:',newArray2);
// 自定义方法
let newArray3 = deepClone(newArray);
console.log('自定义方法拷贝:',newArray3);
// 修改原始数组值
newArray.a = 2;
newArray.c.f = 88;
newArray.d[1] = 99;
newArray3.a = 35;

console.log('原始:',newArray);
console.log('JSON方式拷贝:',newArray2);
console.log('自定义方法拷贝:',newArray3);

自定义方法二 :

const cache = new WeakMap();

function deepClone(value){
    // 原始类型直接返回 或者函数
    if(typeof value !== 'object' || value === null){
        return value
    }
    const cached = cache.get(value);
    if(cached){
        return cached;
    }
    // 判断数据类型
    const result = Array.isArray(value) ? []:{};
    // 设置原型一致
    Object.setPrototypeOf(result,Object.getPrototypeOf(value));
    cache.set(value,result);
    for(let key in value){
        // 深度克隆 (会克隆原型上的)
        // result[key] = deepClone(value[key]);
        if(value.hasOwnProperty(key)){
            result[key] = deepClone(value[key]);
        }
    }
    return result;
}

猜你喜欢

转载自blog.csdn.net/JackieDYH/article/details/130884520
今日推荐