我们知道,javascript中有两种数据类型:
基本数据类型: null undefined number string boolean symbol
引用数据类型: Array Function Object
//基本数据类型
var a = 1;
b = a;
a++;
console.log(a); // 2
console.log(b) // 1
//引用数据类型
var c = {
age: 18
}
c.age = 20;
var d = c;
console.log(c.age);// 20
console.log(d.age)// 20
所以说,基本数据类型的赋值操作,实际上是重新开辟一段内存空间,在把值放到新开辟的内存空间中,因此a和 b实际上在不同的内存空间,互不影响
对于引用数据类型,赋值操作实际上进行的仅仅是复制了一份指向堆内存的指针,归根结底c 和d 只是都指向了一份内存空间,因此改变c 也会同时改变d
浅拷贝
Object.assign()
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
}
}
var o ={};
Object.assign(o, obj);
console.log(o) //此时,o里面的age = 20
o.msg.age = 20;
console.log(obj) //此时,obj里面的age = 20
//obj和o共同指向同一内存空间,因此改变o也会导致obj发生变化
Array.prototype.concat()
var arr = [1,2,{
name:"zs"
}];
var arr2 = arr.concat();
arr2[2].name = "lis";
console.log(arr[2]) // {name:"zs"}
Array.prototype.slice()
var arr = [1,2,{
name:"zs"
}];
var arr3 = arr.slice();
arr3[2].name = "lis";
console.log(arr[2]) // {name:"lis"}
浅拷贝只是拷贝一层,对于更深层次对象级别的只拷贝引用
深拷贝
手动遍历实现深拷贝
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
// 封装函数
function deepCopy(newobj, oldobj) {
for (var k in oldobj) {
// 判断我们的属性值属于那种数据类型
// 1. 获取属性值 oldobj[k]
var item = oldobj[k];
// 2. 判断这个值是否是数组
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item)
} else if (item instanceof Object) {
// 3. 判断这个值是否是对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
// 4. 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(o, obj);
console.log(o);
o.msg.age = 20;
console.log(obj); //此时改变age不会影响obj里的age
深拷贝拷贝多层, 每一级别的数据都会拷贝.