理解深浅拷贝以及深浅拷贝的方法

        先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数

执行结果:调用一次构造函数,调用两次析构函数,两个对象的指针成员所指内存相同,name指针被分配一次内存,但是程序结束时该内存却被释放了两次,会造成内存泄漏问题!

这是由于编译系统在我们没有自己定义拷贝构造函数时,会在拷贝对象时调用默认拷贝构造函数,进行的是浅拷贝!即对指针name拷贝后会出现两个指针指向同一个内存空间。

所以,在对含有指针成员的对象进行拷贝时,必须要自己定义拷贝构造函数,使拷贝后的对象指针成员有自己的内存空间,即进行深拷贝,这样就避免了内存泄漏发生。

执行结果:调用一次构造函数,一次自定义拷贝构造函数,两次析构函数。两个对象的指针成员所指内存不同。

总结:浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。

深拷贝方法:

           1. 使用JSON.parse()与JSON.stringify()对对象进行拷贝

                通常情况下,我们可以使用JSON.parse()与 JSON.stringify()实现对象的深克隆,如下:

                var clone = function (obj) {

                return JSON.parse(JSON.stringify(obj));

                }        //这种方法只适用于纯数据json对象的深度克隆,因为有些时候,这种方法也有缺陷

            2.目前没有发现bug的对象深拷贝方法

             var clone = function (obj) {

                    if(obj === null) return null

                    if(typeof obj !== 'object') return obj;

                    if(obj.constructor===Date) return new Date(obj);

                    if(obj.constructor === RegExp) return new RegExp(obj);

                     var newObj = new obj.constructor ();  //保持继承链

                    for (var key in obj) {

                            if (obj.hasOwnProperty(key)) {  //不遍历其原型链上的属性

                            var val = obj[key];

                            newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; // 使用arguments.callee解除与函数名的耦合

                           }

                } 

                return newObj; 

        };

3.展开运算符进行浅拷贝

        var arr1=[1,2,5,6,4];

        var arr2=[...arr1];

        arr1 == arr2      // false;

你可能感兴趣的:(理解深浅拷贝以及深浅拷贝的方法)