深拷贝与浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。
假设B复制了A,修改A的时候,看B是否发生了变化:
如果B也跟着发生改变,说明是浅拷贝,拿人的手段!!!(修改堆内存中的同一个值)
如果B没改变,说明是浅拷贝,自食其力!!!(修改堆内存中的不同的值)
浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,
深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
浅复制:仅仅是指向被复制的内存地址,如果原地址发生了改变,那么浅复制出来的对象也会相应的改变。
深复制:在计算机中开辟一块新的内存地址用于存放复制的对象。
深拷贝实例:
//此递归方法不包含数组对象
var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
function shallowCopy(src) {
var newobj = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
newobj[prop] = src[prop];
}
}
return newobj;
}
因为浅拷贝只会将对象的各个属性进行复制,并不会进行递归复制,而JavaScript存储对象是存地址的,所以浅拷贝会导致Obj.arr和shallowObj.arr指向同一块地址。
导致的结果就是:
shallowObj.arr=[1]=5;
console.log(obj.arr[i]); //5
var
obj = {
a:1,
arr: [1,2],
nation :
‘中国‘
,
birthplaces:[
‘北京‘
,
‘上海‘
,
‘广州‘
]
};
var
obj2 = {name:
‘杨‘
};
obj2 = deepCopy(obj,obj2);
console.log(obj2);
//深复制,要想达到深复制就需要用递归
function deepCopy(o, c){
var
c = c || {};
for
(
var
i
in
o){
if
(
typeof
o[i] ===
‘object‘
){
if
(o[i].constructor === Array){
//这是数组
c[i] = [];
}
else
{
//这是对象
c[i] = {};
}
deepCopy(o[i], c[i]);
}
else
{
c[i] = o[i];
}
}
return
c;
}
var a=[1,2,3,4,5];
var b=a;
a[0]=2;
console.log(a);
console.log(b);
//因为b浅拷贝a,ab指向同一内存地址(堆内存中存的值)
//b会随着a的变化而变化
//[2, 2, 3, 4, 5]
//[2, 2, 3, 4, 5]
function deepClone(obj)
{
var
newObj = obj instanceof Array ? []:{};
if
(
typeof
obj !==
‘object‘
)
{
return
obj;
}
else
{
for
(
var
i
in
obj)
{
newObj[i] =
typeof
obj[i] ===
‘object‘
? deepClone(obj[i]) : obj[i];
}
}
return
newObj;
}
var
a = [1, 2, 4, 6,
"a"
,
"12"
, [1, 2]];
var
b = deepClone(a);
a[3] = 7;
console.log(a);
console.log(b);
//b对象并没有因为a对象的改变而改变,因为b深拷贝a
[ 1, 2, 4, 7, ‘a‘, ‘12‘, [ 1, 2 ] ]
[ 1, 2, 4, 6, ‘a‘, ‘12‘, [ 1, 2 ] ]
原文:https://www.cnblogs.com/zzlbok/p/14123708.html