深复制对象

要复制的对象

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}
                }
            }
        });
        

深复制函数

function cloneObj(source,target){
            if(target==undefined) 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){  //是对象类型时进入条件
                    var obj;
                   switch(true){
                       case desc.value.constructor===Date:
                       obj=new Date(desc.value.toString());  //是时间类型时:将原来的时间当做参数传入到new Date中,否则因为时间是时刻在变的,复制过来的时间会不一样。
                       break;
                       case desc.value.constructor===RegExp:
                       obj=new RegExp(desc.value.source,desc.value.flags);  //如果是正则类型时:将原正则的source与flags当做参数带入,才能获得和原来一样的正则表达式。
                       break;
                       case HTMLElement.isPrototypeOf(desc.value.constructor):  //判断是否是HTML标签
                       obj=document.createElement(desc.value.nodeName);     //根据原标签的nodeName创建同一类型的HTML标签
                       break;
                       default:
                       obj=new desc.value.constructor();
                       // 内容.constructor可以判断是什么类型的,比如对象就是Object,数组是Array,所以可以利用这点来new一个相同类型的。
                   }
                    Object.defineProperty(target,names[i],{
                        enumerable:desc.enumerable,
                        writable:desc.writable,
                        configurable:desc.configurable,
                        value:obj
                    }); //同时把每个属性的描述对象也给target复制过去
                    cloneObj(desc.value,obj);   //将某个对象类型的属性当做参数递归,clone给上边创建的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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值