拷贝
将一个变量赋值 a 给另一个变量 b
如果a是值类型的数据,赋值后,对b进行修改时,不会对a产生影响。
let a = 222
let b = a
b = 333
console.log(a);//222
console.log(b);//333
但是,如果a是引用类型的数据,如对象是引用类型的数据,赋值后,对b进行修改,会对a产生影响
原因是,只是将a的地址赋值给了数组,所以对b进行修改的时候,也相当于对a进行了修改
let a = {
a: '123',
b: '456'
}
let b = a
b.b = 789
console.log(a); //{a: '123', b: 789}
console.log(b); //{a: '123', b: 789}
所以,如果在赋值时,不想改变原来的变量,就需要拷贝他的值,而不是他的地址
浅拷贝与深拷贝
浅拷贝:只是拷贝一层,更深层次对象级别的只拷贝了地址。
深拷贝:深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来,内容和原对象一样,更改原对象,拷贝对象不会发生变化
浅拷贝
浅拷贝的方式:
- 使用for循环实现
- Object.assign 函数可简单的实现浅拷贝,它是将两个对象的属性叠加后面对象属性会覆盖前面对象同名属性。
- 使用展开语法也可以实现浅拷贝
Object.assign函数:
var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2); // {a:1, b:2, c:3}
- 使用展开语法或Object.assign函数:进行浅拷贝
let aaa = {
name: 'xz',
sex: 'man'
}
let bbb = {...aaa
}
console.log('bbb', bbb); //bbb {name: 'xz', sex: 'man'}
let ccc = {}
Object.assign(ccc, aaa)
console.log('ccc', ccc); //ccc {name: 'xz', sex: 'man'}
- 浅拷贝之后拷贝第一层的属性,如果第一层有引用类型的属性,只会拷贝其地址,这样就会对原来的数据造成影响
let obj = {
xxx: 'xxxx',
zzz: 'xxxzzzz',
hobit: {
sport: 'basketball',
song: '两只老虎'
}
}
let xx = {}
for (let key in obj) {
xx[key] = obj[key]
}
console.log(xx);
但是如果对xx里的hobit属性进行操作,也会影响到obj
深拷贝
利用递归的方法 将 对象里的所有值进行拷贝
判断对象里的属性是不是 object类型,如果是递归调用copy(),不是则直接赋值
let xz = {
name: 'xiaozhuo',
lesson: {
math: 'Math',
english: 'English'
},
}
function copy(obj) {
let cop = {}
for (let key in obj) {
//判断对象里的属性是不是 object类型,如果是递归调用copy(),不是则直接赋值
cop[key] = typeof obj[key] === 'object' ? copy(obj[key]) : obj[key]
}
return cop
}
let lsy = copy(xz)
lsy.lesson.math = 'xxxx'
console.log(xz);
console.log(lsy);
对象里面的属性是数组类型的情况
如果按照上面的方法,会出现将数组类型拷贝成对象类型
let xz = {
name: 'xiaozhuo',
lesson: {
math: 'Math',
english: 'English'
},
arr: [1, 2, 3, 4, 5]
}
function copy(obj) {
let cop = {}
for (let key in obj) {
cop[key] = typeof obj[key] === 'object' ? copy(obj[key]) : obj[key]
}
return cop
}
let lsy = copy(xz)
lsy.lesson.math = 'xxxx'
console.log('xz', xz);
console.log('lsy', lsy);```
正确的方法是 在函数里面声明变量的时候,先判断传进来的参数是对象还是数组
let xz = {
name: 'xiaozhuo',
lesson: {
math: 'Math',
english: 'English'
},
arr: [1, 3, 4, 5, 8]
}
function copy_arr(obj) {
let cop = obj instanceof Array ? [] : {}
//两种都可以
// for (let key in obj) {
// cop[key] = typeof obj[key] == 'object' ? copy_arr(obj[key]) : obj[key]
// }
for (let [k, v] of Object.entries(obj)) {
cop[k] = typeof v == 'object' ? copy_arr(v) : v
}
return cop
}
console.log('Object.entries(xz)', Object.entries(xz));
let lsy = copy_arr(xz)
lsy.arr[0] = 99999
console.log('xz', xz);
console.log('lsy', lsy);