持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
为什么要进行拷贝?
var a = {
a:1
}
var b = a
b.a = 2
当我们通过b.a=2来修改a值时发现,a对象里面的值受到了影响,拷贝就是想要让这两个对象有独立的引用地址空间。
浅拷贝与深拷贝的区别
浅拷贝:实际就是将对象进行一层赋值,深层次的引用地址还是一样,原数据和拷贝后的数据会互相影响 深拷贝:是将对象的每一层进行拷贝,原数据和拷贝后的数据不会互相影响
浅拷贝的实现方式
1.es3方式遍历循环
function simpleClone(obj) {
let result = {}
for(i in obj) {
result[i] = obj[i]
}
return result
}
2.es6方式Object.assign()
var obj1 = {
a:1,
b:2,
c:3,
d:{
e:4,
f:{
g:5
}
}
}
var obj2 = Object.assign({},obj1)
obj2.d.e = 5当执行完这行代码后发现
拷贝的内容修改影响到了原内容,此时Object.assign()方法属于浅拷贝
3.es6方式...扩展运算符
var obj1 = {
a:1,
b:2,
c:3,
d:{
e:4,
f:{
g:5
}
}
}
var obj3 = {...obj1}
尝试修改深层的赋值,发现原内容受到影响,故是浅拷贝。
深拷贝的实现方式
1.基础递归
function deepClone(obj) {
let cloneObj = {}
for(key in obj) {
if(typeof obj[key] === 'object' && obj[key] !== null) {
cloneObj[key] = deepClone(obj[key])
}else {
cloneObj[key] = obj[key]
}
}
return cloneObj
}
2.处理循环引用
let obj = {}
obj.a = obj
此时会出现一个问题,就是出现递归爆栈。 利用map去将已经拷贝对象存起来,去校验一下当前对象是否在map中。
function isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]';
}
function deepClone(obj, hash = new Map()) {
if (!isObject(obj))
return obj;
if (hash.has(obj)) return hash.get(obj);
var target = Array.isArray(obj) ? [] : {};
hash.set(obj, target);
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
if (isObject(obj[key])) {
target[key] = cloneDeep(obj[key], hash);
} else {
target[key] = obj[key]; }
}
}
return target;
}
3.es6中JSON.parse(JSON.stringify())
let obj = {
a:1,
b:2,
c:3,
d:{
e:4,
f:{
g:5
}
}
}
let cloneObj2 = JSON.parse(JSON.stringify(obj))