Javascript 浅拷贝和深拷贝

前言:浅拷贝和深拷贝只针对引用类型,引用类型有Object、Array、Function

一.对象的普通拷贝

var obj1 = {
    id: 1,
    name: "jay",
    age: 18
}

var obj2 = obj1;
obj2.id = 2;
console.log(obj1.id) // 2
console.log(obj2.id) // 2

分析:为什么改变obj2的id属性的值,obj1的id属性的值也会被改变?
对象是引用类型,在栈内存中变量obj1的值保存的实际是该堆内存中的地址信息,所以这样的拷贝只是复制了obj1的地址,而地址都是指向同一个堆内存的空间。
如图:

Javascript 浅拷贝和深拷贝_第1张图片
xxx.png

二.对象的浅拷贝

1.使用浅拷贝解决引用类型只是拷贝地址的问题
var obj1 = {
    id: 1,
    name: "jay",
    age: 18
}

var obj2 = new Object();

for(var key in obj1){
    obj2[key] = obj1[key];
}

obj2.id = 2;
console.log(obj1.id);  // 1
console.log(obj2.id);  // 2

总结:通过上面的分析我知道了,对于引用类型的赋值拷贝只是拷贝对象的值的地址,如果要真正拷贝对象的值,我们可以想到将obj1的值进行遍历拷贝给obj2,这样就实现了对对象值的拷贝,改变obj1和obj2有两块不同的内存空间,改变其中一个属性值,不会影响到另一个的属性值。

2.使用浅拷贝无法拷贝内嵌的对象
  var obj1 = {
    id: 1,
    name: "jack",
    age: 18,
    dog: {
        name: '旺财',
        age: 10,
    }
}

var obj2 = new Object();

for(var key in obj1){
    obj2[key] = obj1[key];
}

obj2.dog.name = "二哈";
console.log(obj2.dog.name);  // 二哈
console.log(obj2.dog.name);  // 二哈

分析:对于属性均为基本数据类型的对象的来说,使用浅拷贝一次遍历就能成功复制对象的属性值,但是如果对象的属性又是对象的话,再通过一次外层的遍历是无法再成功拷贝!

三.对象的深拷贝

1.使用深拷贝解决浅拷贝的问题
var obj1 = {
    id: 1,
    name: "jack",
    age: 18,
    dog: {
        name: '旺财',
        age: 10,
    }
}

function deepCopy(obj1,obj2){
    for(var key in obj1){
        var item = obj1[key];

        //如果item是对象类型
        if (item instanceof Object) {
            obj2[key] = {};
            deepCopy(item,obj2[key])

        //如果item是数组类型
        }else if(item instanceof Array){
            obj2[key] = [];
            deepCopy(itme,obj2[key]);

        //如果item是基本类型   
        }else{
            obj2[key] = obj1[key];
        }
    }
}

var obj2 = new Object();
deepCopy(obj1,obj2);
obj2.dog.name = "金毛";
console.log(obj1.dog.name);
console.log(obj2.dog.name);

总结:深拷贝是在遍历时对内部的属性做了判断,如果遇到属性是引用类型,就会进行再次遍历,直至遍历到基本类型为止。

你可能感兴趣的:(Javascript 浅拷贝和深拷贝)