nodom2改造-js对象深度合并

原创
2019/01/21 00:02
阅读数 40

首先增加了Object的clone方法,代码如下:

/**
     * 对象复制
     * @param expKey    不复制的键正则表达式或名
     * @return          复制的对象
     */

    Object.prototype.clone = function(expKey){
        let map = new WeakMap();
        let src = this;
        let retObj = clone(src);
        map = null;
        return retObj;

        /**
         * clone对象
         * @param src   待clone对象
         * @return      克隆后的对象
         */
        function clone(src){
            function clone(src){
            var dst;
            if(nodom.isObject(src)){
                dst = new Object();
                //把对象加入map,如果后面有新克隆对象,则用新克隆对象进行覆盖
                map.set(src,dst);
                Object.getOwnPropertyNames(src).forEach((prop)=>{
                    //不克隆的键
                    if(expKey){
                        if(expKey.constructor === RegExp && expKey.test(prop) //正则表达式匹配的键不复制
                            || expKey.constructor === String && expKey === prop   //被排除的键不复制
                            ){
                            return;
                        }
                    }
                    //数组或对象继续克隆
                    if(nodom.isObject(src[prop]) || nodom.isArray(src[prop])){
                        let co = null;
                        if(!map.has(src[prop])){  //clone新对象
                            co = clone(src[prop]);
                            //存储已克隆对象,避免重复创建或对象相互引用带来的溢出
                            map.set(src[prop],co);
                        }else{                    //从map中获取对象
                            co = map.get(src[prop]);
                        }
                        dst[prop] = co;
                    }else{  //直接复制
                        dst[prop] = src[prop];
                    }
                });
            } else if(nodom.isArray(src)){
                dst = new Array();
                //把对象加入map,如果后面有新克隆对象,则用新克隆对象进行覆盖
                map.set(src,dst);
            
                src.forEach(function(item,i){
                   if(nodom.isObject(item) || nodom.isArray(item)){
                        dst[i] = clone(item);
                    }else{  //直接复制
                        dst[i] = item;
                    } 
                });
            }
            return dst;
        }
    }
 }());

改写merge方法,调用了Object.assign方法和Object的clone(见上面扩展)方法:

/**
     * 合并多个对象并返回
     * @param   参数数组
     * @return  返回对象
     */
    static merge(){
        for(let i=0;i<arguments.length;i++){
            if(!nodom.isObject(arguments[i])){
                throw nodom.Error.handle('invoke','nodom.merge',i,'object');    
            }
        }

        let retObj = Object.assign.apply(null,arguments);
        
        subObj(retObj);
        return retObj;
        //处理子对象
        function subObj(retObj){
            for(let o in retObj){
                if(nodom.isObject(retObj[o]) || nodom.isArray(retObj[o])){ //对象或数组
                    retObj[o] = retObj[o].clone();
                }
            }
        }
    }

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部