博客地址:https://ainyi.com/72
JavaScript 程序中,对于简单的数字、字符串可以通过 = 赋值拷贝
但是对于数组、对象、对象数组的拷贝,就有浅拷贝和深拷贝之分
浅拷贝就是当改变了拷贝后的数据,原数据也会相应改变
来说说深拷贝
不推荐此方法
let a = [1, 2, 3]
let b = []
for (let val of a) {
b.push(val)
}
b.push(4)
a // [1, 2, 3]
b // [1, 2, 3, 4]
数组方法 slice() 可从已有的数组中返回选定的元素
那么设置为 0,就是返回整个数组
let a = [1, 2, 3]
let b = a.slice(0)
b.push(4)
a // [1, 2, 3]
b // [1, 2, 3, 4]
数组方法 concat() 连接一个或多个数组,并返回一个副本
那么不设置参数,就返回本数组
let a = [1, 2, 3]
let b = a.concat()
b.push(4)
a // [1, 2, 3]
b // [1, 2, 3, 4]
let a = [1, 2, 3]
let b = [...a]
b.push(4)
a // [1, 2, 3]
b // [1, 2, 3, 4]
let a = [1, 2, 3]
let b = Array.from(a)
b.push(4)
a // [1, 2, 3]
b // [1, 2, 3, 4]
Object.assign(target, obj)
let a = { name: 'krry' }
let b = Object.assign({}, a)
b.name = 'lily'
a // { name: 'krry' }
b // { name: 'lily' }
注意使用 assign() 有如下特点:
let a = { name: 'krry' }
let b = { ...a }
b.name = 'lily'
a // { name: 'krry' }
b // { name: 'lily' }
以上是简单数组、对象的深拷贝方法,但是对于二维数组、对象数组、对象里包含对象,以上方法均达不到深拷贝方法
以上只能达到数组、对象的第一层的==深拷贝==,对于里面的数组或对象属性则是==浅拷贝==,因为里面的内存地址只是拷贝了一份,但都是指向==同一个地址==
所以当改变数组、对象里的数组元素或对象,原数据依然会改变
使用 JSON.parse(JSON.stringify(obj))
let a = [1, [2, {aa: 2}, [4]], {aa: 5, cc: { dd: 6 }}]
let b = JSON.parse(JSON.stringify(a)) // 完美
通过 JSON.stringify 实现深拷贝有几点要注意
function deepCopy(obj) {
let result = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
result[key] = deepCopy(obj[key]); // 递归复制
} else {
result[key] = obj[key];
}
}
}
return result;
}
使用 lodash 插件的深拷贝方法
// 官方例子
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
传送门:https://www.lodashjs.com/docs/4.17.5.html#cloneDeep
博客地址:https://ainyi.com/72
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。