• JavaScript之复杂对象的深拷贝(完全深拷贝)


    由于网上很多的深拷贝大都有如下问题:

      1.灵活性。不能应对复杂对象(复杂对象是指:单一数组对象、多数组对象、多非数组对象、单一对象组合形成的复杂对象)的灵活拷贝

      2.不变性。即 拷贝的对象与原对象的结构发生了变化(尤其是:将数组对象经过拷贝后人为变成了非数组对象),破坏了结构并不是深拷贝的初衷。

    依据上述问题,花费了三个小时左右的思考和调试,得以解决。

    声明:如需读者记录笔记或者摘要时,请声明引用出处,以尊重劳动成果~,谢谢,当然也可以向博主提出意见~

    //判断是否为字符串
    //返回类型:
    //{baseType:typeof(arg),numberType:'int','float',-1}
    function numberType(arg){
        var baseType;
        var numberType;
        var regx_int =  /^[0-9]*[1-9][0-9]*$/;
        if(!isNaN(arg)){//JavaScript中,属于数值的有:数值型字符串和真实数值       
            baseType = typeof(arg);//输出:string or number
            if(regx_int.test(arg)){//整数
                numberType = "int";
            } else {
                numberType = "float";
            }
        } else {
            baseType = typeof(arg);
            numberType = -1;
        }
    
        return {
            "arg":arg,
            "baseType": baseType,//注意:typeof(stringNumber):string
            "numberType": numberType
        }
    }
    /*
        console.log(numberType("23"));  //{arg: "23", baseType: "string", numberType: "int"}
        console.log(numberType("23.0"));//{arg: "23.0", baseType: "string", numberType: "float"}
        console.log(numberType("23a")); //{arg: "23a", baseType: "string", numberType: -1}
        console.log(numberType(23));    //{arg: 23, baseType: "number", numberType: "int"}
        console.log(numberType(23.0));  //{arg: 23, baseType: "number", numberType: "int"}
     */
    
    //url:[js中的深拷贝和浅拷贝](http://www.jianshu.com/p/70dc5b968767)
    //依赖:recursion(obj, data)
    function cloneDeep(obj){
        
        if( typeof obj !== 'object' || Object.keys(obj).length === 0 ){
            return obj
        }
    
        let resultData;
        if( typeof obj == 'object' && (obj instanceof Array))
            resultData = [];
        else {
            resultData = {};
        }
    
        return recursion(obj, resultData)
    }
    
    //url:[js中的深拷贝和浅拷贝](http://www.jianshu.com/p/70dc5b968767)
    //被依赖:cloneDeep(obj)
    //依赖:numberType(num)
    function recursion(obj, data = {}){
        // console.log('[recursion] data:"' + data + '"; execute: obj:', obj);
        for(key in obj){//注意:使用for Each遍历时,会将数值转型为string类型
                // console.log('cur:' + obj + '[' + key + ']:', obj[key]);
                if( (typeof obj[key] == 'object') && (obj[key] instanceof Array) && Object.keys(obj[key].length > 0 )){
                    // console.log('key[' + key + '] is Array:', obj[key]);
                    var array = new Array();
                    for(var i = 0, size = obj[key].length; i < size; i++){
                        (function(index){
                            array.push((obj[key][index]));
                        })(i)
                    }
                    data[key] = array;
                    // console.log('data[key] data:', data[key]);
                } 
                else if( (typeof obj[key] == 'object') && (!(obj[key] instanceof Array)) && Object.keys(obj[key].length > 0 )){
                    // console.log('key[' + key + '] is Object but not Array:', obj[key]);
                    data[key] = recursion(obj[key], {});
                    // console.log('data[key] data:', data[key]);
                } else {
                    // console.log('key[', key, '] is not object, ','key is ',typeof(key), ', obj[key]:' + obj[key] + ' is ',typeof(key));
                    var nType = numberType(key);
                    if(nType.baseType == "string"){//由于forEach的原因,所有的key都是字符串或者对象
                        // console.log('* nType:', nType);
                        // console.log('* data.push(obj[key]):', data.push(obj[key]));
                        // console.log('* obj[key] instanceof Array:', obj[key] instanceof Array);
                        if(nType.numberType == -1){//如果是真实的字符串或者非数值类型(即 非数值字符串或 真实数值类型),则说明是对象的一个属性
                            data[key] = obj[key];
                        } else {//反之:该属性为真实数值类型,说明key作为数组的(下标)键值
                            data.push(obj[key]);
                            // console.log('test obj[key]:', obj[key]);
                        }
                    }
                    data[key] = obj[key];//实际上,此处无过多实际意义和用意
                    // console.log('data[ ' + key +' ] data:', data[key]);
                }
                // console.log('___________________________________[data]_________________________:', data);//test:遍历一次时,查看当前拷贝对象data的状态
            }
        return data;
    }
    

    使用方式与测试:

    var courses = [{"name":"面向对象分析与设计","week_index":1,"course_index":[2,3],"week_start":5,"week_end":16,"teacher":"王敏","location":"6B-108多媒体286座(2017-2018-2)-150905319-0120030135-1"}];
    // typeof(courses);
    newCourses = recursion(courses, []);
     
    studentCourses = cloneDeep(student); 
    
    console.log(studentCourses,newCourses); 
    

      

    效果:

  • 相关阅读:
    第一节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表
    Tensorflow 错误:Unknown command line flag 'f'
    Python 多线程总结
    Git 强制拉取覆盖本地所有文件
    Hive常用函数 傻瓜学习笔记 附完整示例
    Linux 删除指定大小(范围)的文件
    Python 操作 HBase —— Trift Trift2 Happybase 安装使用
    梯度消失 梯度爆炸 梯度偏置 梯度饱和 梯度死亡 文献收藏
    Embedding 文献收藏
    深度学习在CTR预估中的应用 文献收藏
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/7992167.html
Copyright © 2020-2023  润新知