js中的深复制

需求:

1.既可以广度复制,也能深度复制
2.复制的类型包括Date,HTML,正则,数组,对象,基础类型,可枚举的,不可枚举的等
3.深层的属性值改变,复制过去的不发生改变

下面来看代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
      //复制对象的举例
        var obj={
            a:1,
            b:2,
            c:[1,2,3],
            z:document.createElement("div"),
            d:{
                e:new Date(),
                f:/a/g,
                g:function(s){
                    console.log(s);
                },
                h:{

                }
            }
        }
        Object.defineProperties(obj.d.h,{
            i:{
                value:10
            },
            j:{
                configurable:true,
                value:[1,2,3,4]
            },
            k:{
                writable:true,
                value:{
                    l:{},
                    m:"abcde",
                    n:true,
                    o:[1,2,3]
                }
            }
        })

        Object.defineProperties(obj.d.h.k.l,{
            p:{
                value:function(){
                    console.log("p")
                }
            },
            q:{
                value:{
                    r:{a:1},
                    j:{b:2}
                }
            }
        });
      

        console.log(obj);
        
        function cloneObj(source,target){
            // if(target==undefined) target={};
            target=target||{};
            var names=Object.getOwnPropertyNames(source);  //为了遍历不可枚举属性  获取对象的所有属性
            for(var i=0;i<names.length;i++){
                var desc=Object.getOwnPropertyDescriptor(source,names[i]);   //获取对象属性的描述属性
                if(typeof desc.value==="object" && desc.value!==null){   //不是object的只有五种基本类型
                    var obj;
                   switch(true){
                       case desc.value.constructor===Date:
                       obj=new Date(desc.value.toString());
                       break;
                       case desc.value.constructor===RegExp:
                       obj=new RegExp(desc.value.source,desc.value.flags);
                       break;
                       case HTMLElement.isPrototypeOf(desc.value.constructor):
                       obj=document.createElement(desc.value.nodeName);
                       break;
                       default:
                       obj=new desc.value.constructor()   //根据属性值的类型来创建obj(如果是数组,复制数组,如果对象,就复制对象)
                   }
                    Object.defineProperty(target,names[i],{
                        enumerable:desc.enumerable,
                        writable:desc.writable,
                        configurable:desc.configurable,
                        value:obj
                    });
                    cloneObj(desc.value,obj);
                }else{
                    Object.defineProperty(target,names[i],desc)
                } 
            }
            return target;
        }

        var o={a:1};
        o=cloneObj(obj);
        obj.d.h.j[1]=100;
        console.log(o);


       
   
    </script>
</body>
</html>
posted on 2020-08-12 19:08  94Lucky  阅读(167)  评论(0编辑  收藏  举报