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.youkuaiyun.com/m0_50665842/article/details/127991432