深浅拷贝定义
- 浅拷贝 只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值也会随之变化
- 深拷贝 将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变
- 面试中可以这样说,浅拷贝是拷贝一层,深层次的对象级别就拷贝引用,深拷贝是拷贝多层,每一层的数据都会拷贝
// 深拷贝 number string boolean null undefined
let c = 1
const d = c
c = 2
console.log(c) // 2
console.log(d) // 1
// 浅拷贝 obj array
const aa = { name: 'mmmmmmmm', id: 1 }
const bb = aa //直接赋值
aa.name = 'kkkkkkkkkk'
console.log(aa) // { name: 'kkkkkkkkkk', id: 1}
console.log(bb) // { name: 'kkkkkkkkkk', id: 1}
const aa = { name: 'mmmmmmmm', id: 1 }
const bb = {...aa} // 对象扩展符 第一级是深拷贝,第二级是浅拷贝
aa.name = 'kkkkkkkkkk'
console.log(aa) // { name: 'mmmmmmmm', id: 1}
console.log(bb) // { name: 'kkkkkkkkkk', id: 1}
const e = { name: 'good', test: { name: 'test' } }
const f = Object.assign({}, e) // 第一级是深拷贝,第二级是浅拷贝
f.name = 'bad'
f.test.name = 'testname'
console.log(e) // { name: "good",test: { name: "testname" }}
console.log(f) // { name: "bad",test: { name: "testname" }}
const h = { name: { test: 'test' } }
const i = Object.assign({}, h)
h.name.test = 'bad'
console.log(h) // { name: { test: "bad" }}
console.log(i) // { name: { test: "bad" }}
实现深拷贝的方法
// 使用递归的方式实现深拷贝
function deepClone(obj) {
const objClone = Array.isArray(obj) ? [] : {} // 判断复制的目标是数组还是对象
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === Object) {
objClone[key] = obj[key].constructor === Array ? [] : {} // 如果值是对象就递归一下自己
objClone[key] = deepClone(obj[key])
} else {
// 如果不是,就直接赋值
objClone[key] = obj[key]
}
}
}
return objClone
}
const a = [1, 2, 3, { name: 'mmmmmmmm', id: 1 }]
const b = deepClone(a)
a.name = 'kkkkkkkkkk'
console.log(a) // [1, 2, 3, { name: 'kkkkkkkkkk', id: 1 }]
console.log(b) // [1, 2, 3, { name: 'mmmmmmmm', id: 1 }]
// 通过js的内置对象JSON来进行数组对象的深拷贝
// 注意:这种方法无法实现对对象中方法的深拷贝
const a = [1, 2, 3, { name: 'mmmmmmmm', id: 1 }]
const b = JSON.parse(JSON.stringify(a))
a.name = 'kkkkkkkkkk'
console.log(a) // [1, 2, 3, { name: 'kkkkkkkkkk', id: 1 }]
console.log(b) // [1, 2, 3, { name: 'mmmmmmmm', id: 1 }]
//通过jQuery的extend方法实现深拷贝
var array = [1,2,3,4];
var newArray = $.extend(true,[],array);
//Object.assign() 拷贝 concat() slice()针对数组 第一层是深拷贝,第二层是浅拷贝
当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。