JS对象的深复制

JS实现对象的深复制

function cloneObject(source,target){
            var list=["number","string","boolean","undefined","null","function"];
            if(target===undefined){
                // 判断源对象是否是HTML标签
                if(HTMLElement.prototype.isPrototypeOf(source)){
                    // 根据这个源对象的nodeName创建一个DOM对象
                    target=source.cloneNode(false);
                }else{
                    // 根据源对象的构造函数创建一个新对象
                    target=new source.constructor();
                }
            }
            // 获取源对象中所有的属性名
            var names=Object.getOwnPropertyNames(source);
            // 遍历所有属性名
            for(var i=0;i<names.length;i++){
                // 获取源对象中该属性名的描述对象
                var desc=Object.getOwnPropertyDescriptor(source,names[i]);
                // 判断该属性的值是否是基础数据类型
                if(list.includes(typeof desc.value)){
                    // 如果是基础数据类型,直接将该描述对象设置给目标对象的该属性
                    Object.defineProperty(target,names[i],desc);
                }else{
                    // 创建一个新引用型属性值
                    var t;
                    // 因为DOM是特殊不能使用new创建,因此判断该对象是否是DOM类型
                    if(HTMLElement.prototype.isPrototypeOf(desc.value)){
                          t=desc.value.cloneNode(false);
                        //   复制这个类型给这个对象
                    }else{
                        // 将属性值的类型分类判断
                        switch(desc.value.constructor){
                            case RegExp:
                            // 如果正则表达式时,需要将source和flags带入
                               t=new RegExp(desc.value.source,desc.value.flags);
                            break;
                            case Date:
                            // 日期属性需要将日期直接带入
                                t=new Date(desc.value);
                            break;
                            case Symbol:
                            // 直接创建Symbol,不能复制相同
                                t=Symbol();
                            break;
                            case Set:
                            // Set类型需要将values带入set
                                t=new Set(desc.value.values());
                                break;
                            break
                            case Map:
                            // map需要将entries带入map
                                t=new Map(desc.value.entries());
                                break;
                           default:
                            // 其他,包括数组和对象可以直接创建新的类别
                              t=new desc.value.constructor();
                            break;
                           
                        }
                    }
                    // 将描述对象的各种值设置给该对象的属性
                    var o={}
                    o.value=t;
                    if(desc.enumerable)o.enumerable=desc.enumerable;
                    if(desc.writable)o.writable=desc.writable;
                    if(desc.configurable)o.configurable=desc.configurable;
                    if(desc.set) o.set=desc.set;
                    if(desc.get) o.get=desc.get;
                    Object.defineProperty(target,names[i],o);
                    // 递归将获取的该属性值复制给创建的这个引用对象
                    cloneObject(desc.value,t);
                }
            }
            return target;
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值