一个引用对象一般来说由两个部分组成:一个具名的Handle,也就是我们所说的声明(如变量)和一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增引用对象的New方法是进行创建。
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响( 指的是拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝。这样进行深拷贝后的拷贝对象就和源对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。)
浅拷贝:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的时候,指向这个内存空间的所有指针需要重新定义,不然会造成野指针错误。
深拷贝的方法
1.JSON.parser(JSON.stringfy(obj));
【注意】如果obj里面有undefined或者function时,不会被拷贝过去
el:
var obj={
a:1,
b:2,
c:undefined,
fn:function(){}
}
var b=JSON.parse(JSON.stringify(obj));
console.log(b);
console.log(obj);
console.log(b===obj);
a: 1b: 2
a: 1b: 2c: undefined fn: ? ()
false
2.递归
function deepCopy(obj){
var newobj=Array.isArray(obj)?[]:{};
for(let item in obj){
if(typeof(obj[item])=="object" && obj[item]){
newobj[item]=deepCopy(obj[item]);
} else{
newobj[item]=obj[item];
}
}
return newobj
}
console.log(deepCopy(obj),obj);
console.log(deepCopy(obj)===obj); //false
3.利用数组的Array.prototype.forEach进copy
let deepClone = function (obj) {
let copy = Object.create(Object.getPrototypeOf(obj));
let propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function (items) {
let item = Object.getOwnPropertyDescriptor(obj, items);
Object.defineProperty(copy, items, item);
});
return copy;
};
let testObj = {
name: "weiqiujuan",
sex: "girl",
age: 22,
favorite: "play",
family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);
Object.assign() 只是一级属性复制,比浅拷贝多深拷贝了一层而已。除第一层外不在深拷贝
var obj={
a:1,
b:{
c:1,
d:2
},
e:function(){
}
}
var obj1=Object.assign({},obj);
obj1.m=10;
obj1.b.c=444;
obj1.n={kk:000}
console.log(obj1,obj,"iiiiiii");
console.log(obj1===obj)//false
1.obj1
{a: 1, b: {…}, e: ?, m: 10, n: {…}}
1.
a: 1
2.
b: {c: 444, d: 2}
3.
e: ? ()
4.
m: 10
5.
n: {kk: 0}
6.
__proto__: Object
2.obj
{a: 1, b: {…}, e: ?}
1.
a: 1
2.
b: {c: 444, d: 2}
3.
e: ? ()
4.
proto: Object
//第一层为深拷贝,改变obj1里面第一层的数据时obj不会发生改变,但是改变obj1的第二层的时候,obj会发生改变,所以第二层是浅拷贝
浅拷贝的方法:
var obj={
a:1,
b:{
a:1,
b:2
},
c:function(){
}
}
var b=obj;
b.a=10;
console.log(b,obj);
b.b.a=10;
console.log(b,obj)
console.log(b===obj)
//当改变b里面的属性值的时候obj里面相应的属性值也会发生改变