首先我们知道js有两种数据类型,一种是基本数据类型,包括(null,undefined,String,Number,Boolen),这几种数据类型在内存中有固定的大小和空间,另外一种就是引用数据类型,如Object,这种值大小不固定,可以动态添加属性和方法,而基本数据类型是不可以的。
基本数据类型保存在栈中,引用数据类型保存在堆中,栈内存中保存着指向堆内存的指针,
引用类型浅拷贝
let foo = {
a:3,
b:4,
}
let newFoo = foo;
newFoo.a = 6;
console.log(foo)// {a:6,b:4}
如何让Foo的数据不改变,使用Object.assign()解决问题,
let foo = {
a:3,
b:4,
}
let newfoo ={}
Object.assign(newfoo,foo)
newfoo.a=8;
console.log(foo);//{a:3,b:4}
这种方式虽然没改变foo的值,但是也称之为浅拷贝,看一个更深层的例子
let foo = {
a:{
c:1
},
b:4,
}
let newfoo ={}
Object.assign(newfoo,foo)
newfoo.a.c=8;
console.log(foo);//{a:{c:8},b:4}
此时C的结果发生了改变,已经变成了8,这就是浅拷贝,只拷贝了最浅的层的对象,当对象里面嵌套的对象发生改变时,其内部值也会发生改变,没有达到完全隔离的效果,只实现了浅层的拷贝。
引用类型的深拷贝
实现深拷贝的方式常用json,
JSON有两个方法JSON.parse()和JSON.stringify(),前者可以将JSON字符串转换成对象,后者将对象转换成字符串
JSON有两个方法JSON.parse()
和JSON.stringify()
,前者可以将JSON字符串转换成JavaScript对象,后者可以将JavaScript对象转换成JSON字符串。
let foo ={
a:{
c:1
},
b:20
}
let STR = JSON.stringify(foo );
let newfoo = JSON.parse(STR);
newfoo.a.c=10
console.log(foo)//{a:{c:1},b:20}
解决思路是先将引用型数据类型变成JSON,再将其从JSON变回来,这样经过这样一层转换,就会要求计算机从内存中重新开辟一块新的内存空间,foo 和newfoo就没没有任何联系了,就实现了深拷贝