JavaScript——深度克隆

为什么要使用深度克隆?

    直接克隆的话,克隆类中的数组只是获得了原始类中的数组指向。这样的话,原始类和克隆类中的数组指向同一个空间,当你需要操作克隆类中的数组时,原始类的数组也会跟着改变,这一点是相当不可以的,也不符合逻辑。

在克隆之前,我们得先搞清楚,我们需要克隆些什么内容。

    以obj为例,我们进行分析:

        var obj = {

            name : "嫖老师",

            age : 18,

            hobbies : ['basketball', 'JavaScript', 'Vue'] ,

            family : {

                name : "皮皮欢乐家庭",

                parents : {

                    father : "大皮皮",

                    mother : "皮皮妈"

                }

            }

        }

    我们可以直观的看出来obj中有原始值和引用值。引用值为数组和对象,其中对象中,又有原始值name和引用值parents,parents中又有原始值father、mather。说明,想要完成深度克隆,必须嵌套循环实现。我们需要一层一层的进行克隆。

    首先我们使用 for in 遍历出obj中的所有元素,再加以判断。基本思想可以总结为5个过程:

        1、遍历对象 for (var prop in obj)

        2、判断是不是原始值 (使用typeof()判断)

        3、判断是数组还是对象(使用toString()判断)

        4、建立响应的数组或对象

        5、递归

代码演示:

     function deepClone(origin, target) {    //传参 origin 被克隆的类 ,target 需要克隆的类

            var target = target || {};  //当没有传target时,给创建个空类

            toStr = Object.prototype.toString,  //把toString方法应用出来

            arrStr = "[object Array]"   //先设定一个array的toString返回值,方便比较

            for(var prop in origin) {   //用for in 循环origin中所有的属性

                if(origin.hasOwnProperty(prop)) { //判断所得的属性是否是自身的属性,不能使用原型链上的属性

                    if(origin[prop] !== "null" && typeof(origin[prop]) == 'object') {  //为turn时,该属性为引用值。为false时,该元素为原始值,并且这个属性不能为null,为null克隆就没有意义

                        //走到这一步,就可以明确,只有数组和类俩种情况,在进行判断 

                        if(toStr.call(origin[prop]) == arrStr) {    //判断是不是数组

                            target[prop] = [];  //是数组创建一个空数组

                        }else {

                            target[prop] = {};  //不是数组,就只能是类了

                        }

                        //在一个类中,也可能有原始值、数组、类三种情况所有,我们需要再次对这个类再进行循环

                        //此时,循环的出口就是,当该属性为原始值,所有以当前的prop再次调用循环,就可以实现循环递归

                        deepClone(origin[prop],target[prop]);   

                    }else {

                        target[prop] = origin[prop];    //直接赋值

                    }

                }

            }

        }

运行结果演示:


成功克隆

给obj1.hobbies数组push一个数据,看看obj中的hobbies是否有影响



没有影响

    深度克隆成功,俩个hobbies的空间指向并不是同一个,达成了我们的需求。

你可能感兴趣的:(JavaScript——深度克隆)