JavaScript深拷贝实现原理简析


JavaScript实现继承的时候,需要进行对象的拷贝;而为了不影响拷贝后的数据对原数据造成影响,也就是存在共享关系的时候,我们就需要进行深拷贝;

这里就做一个简单的分析其实现原理

先上代码:

var obj1 = {
    name : 'Awen',
    song : {
        auther : '小明',
        title : '广州'
    },
    hobby: ['吃','吃吃','吃吃吃']
};
var obj2 = {};
for (var k in obj1) {
    obj2[k] = obj1[k];
}

console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj2['hobby'].push('喝');
console.log(obj1); //Object {name: "Awen", song: Object, hobby: Array[4]}
console.log(obj2); //Object {name: "Awen", song: Object, hobby: Array[4]}

从图中得到结论:浅拷贝不能完成需求,对于属性是对象的时候,只是进行简单的地址拷贝,其引用关系也在;不符合我们的要求;

在来看下深拷贝:

function inCopy(obj1,obj2) {
    var obj1 = obj1 || {};//容错处理
    for (var k in obj2) { 
        if(obj2.hasOwnProperty(k)){ //只拷贝实例属性,不进行原型的拷贝
            if(typeof obj2[k] == 'object') { //引用类型的数据单独处理
                obj1[k] = Array.isArray(obj2[k])?[]:{};
                inCopy(obj1[k],obj2[k]); //递归处理引用类型数据
            }else{
                obj1[k] = obj2[k]; //值类型的数据直接进行拷贝
            }
        }
    }
}

//深拷贝 两者之间改变互不影响

//1 拷贝后两者之间不再存在共享关系

//2 拷贝之后数据类型不能发生改变,也就是需要判断是数组的时候,需要进行单独递归的遍历

//3 在继承的时候,我们通过原型属性实现原型对象属性的继承,在进行深拷贝的时候,我们首先需要提出原型对象上的属性;通过hasOwnProperty方法来进行筛选;

测试代码及结果如下

var obj3 = {
    name : 'Awen',
    song : {
        auther : '小明',
        title : '广州'
    },
    hobby : ['吃','吃吃','吃吃吃']
};
var obj4 = {};

inCopy(obj4,obj3);
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[3]}
obj4.hobby.pop(); 
console.log(obj3); //Object {name: "Awen", song: Object, hobby: Array[3]}
console.log(obj4); //Object {name: "Awen", song: Object, hobby: Array[2]}
obj4.song.title = '北京';
console.log(obj3);
console.log(obj4);

1 删除新对象的数据最后一项;(互不影响)

JavaScript深拷贝实现原理简析附代码

obj4动态pop最后一项

2 动态修改对象属性,不影响原对象,引用关系切断

JavaScript深拷贝实现原理简析附代码

obj4动态改变

3 拷贝后数据类型保持一致

JavaScript深拷贝实现原理简析附代码

数据类型未发生改变

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM