Javascript实现深拷贝的方式

Javascript实现深拷贝的方式

概念介绍

  • 深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象;
  • 浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。

简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

方法一

ES6新特性

const clone = {...original}

示例

let a = {key1: 1}
let b = {...a}
b.key1 = 2
console.log(a) // {key1: 1}
console.log(b) // {key1: 2}

注意: 这种方式只能用于单层json对象,也就是对象中的每个value都是基本类型,没有嵌套。

方法二

ES6新特性

const clone = Object.assign({}, original)

示例

let a = { key1: 1 };
let b = Object.assign({}, a);
b.key1 = 2
console.log(a) // {key1: 1}
console.log(b) // {key1: 2}

注意: 这种方式只能用于单层json对象,也就是对象中的每个value都是基本类型,没有嵌套。

方法三

const clone = JSON.parse(JSON.stringify(original));

这个是可以对多层json对象进行拷贝的

示例

let a = { 
          	key1: {
            	subKey: 1
          	}
       	 };
let b = JSON.parse(JSON.stringify(a));
b.key1.subKey = 2
console.log(a)
console.log(b)
//打印结果
{
  key1: {
          subKey: 1
        }
}
{
  key1: {
          subKey: 2
        }
}

注意: 使用这个方法,对象中不能有Date, functions, undefined, Infinity, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays这些数据类型。

方法四

递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝。

// 创建一个  原对象,包含字符串,对象,函数,数组等不同类型。
const obj = {
    name: '码小白',
    age: '22',
    skills: {
        javascript: '一知半解',
        css: '比上一个强一点'
    },
    'hope-salary':30000,
    arr: [1, 2, 3, ['a', 'b', 'c']],
    sayHi: () => {
        console.log('能点一个赞就最好了');
    }
}
function copy(obj) {
    // 创建一个空对象用来拷贝之后的内容
    let newObj = {}
    //判断数据是否为 复杂数据类型
    if (typeof obj === 'object') {
        // 是 就将该数据进行 遍历
        for (let k in obj) {
            // 当 obj[k] 的值依然为 复杂数据类型时 重新调用该函数 
            // 将obj[k] 当实参 进行调用 直至 obj[k] 的值不在为 复杂数据类型
            newObj[k] = copy(obj[k])
        }
    } else {
        newObj = obj
    }
    // 将 copy 的对象返回出去(不写 return 会得到 undefined)
    return newObj
}
const copyObj = copy(obj)
//当对象的属性为 字符串时 最好不要用 对象.属性名 
copyObj['hope-salary'] = 100000
console.log(obj);
console.log(copyObj);

方法五

使用第三方库

例如:

总结

进行深拷贝的方法:

  • JSON.stringify() 和JSON.parse() ; (不推荐使用,如果遇到Function,Date等类型的变量容易出现一些意料之外的问题)
  • 递归函数 (推荐使用,项目中使用的更多,更小,更安全)
  • 第三方库lodash的cloneDeep()方法 (就情况而定,如果项目中原先就有lodash这个第三方库,可以使用,否则还是推荐使用递归函数。不然成本太高。)
  • JQuery的extend()函数 (推荐在JQuery项目中使用,其他项目依然推荐是用递归函数)

参考链接

更好的理解基础类型和引用类型的存储过程 https://www.jb51.net/article/252360.htm
https://blog.csdn.net/m0_50665842/article/details/127991432

猜你喜欢

转载自blog.csdn.net/XUELINGMM/article/details/128803668