首页 > 其他 > 详细

对象深复制(面试重点)

时间:2020-05-16 15:45:15      阅读:62      评论:0      收藏:0      [点我收藏+]
<!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>
        // SSS

        var obj={
            a:1,
            b:"aaa",
            c:false,
            d:{
                e:[3,4,6,8,9],
                f:null,
                g:[
                    {id:1,name:"abc",price:100,tag:["自营","特价"]},
                    {id:2,name:"def",price:200,tag:["自营"]},
                    {id:3,name:"ghi",price:300,tag:["自营","特价","双十一"]},
                    {id:4,name:"gkl",price:400,tag:["专柜","双十一"]}
                ],
                h:{
                    i:/^(?=\D+\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,16}$/i,
                    j:new Date(),
                    k:{

                    }
                }
            }
        }
        Object.defineProperties(obj.d.h.k,{
            l:{
                value:[
                [1,2,3,4],
                [1,4,3,4],
                [1,6,3,4],
                ]
            },
            m:{
                enumerable:true,
                value:document.createElement("div")
            },
            n:{
                writable:true,
                value:{
                    o:[1,2,3],
                }
            }
        })


    //   var o=JSON.parse(JSON.stringify(obj));
    //   console.log(o,obj);

        function cloneObj(source,target){
            // 如果目标对象不存在,根据源对象的类型创建一个目标对象
            if(!target) target=new source.constructor();
            // 获取源对象的所有属性名,包括可枚举和不可枚举
            var names=Object.getOwnPropertyNames(source);
            // 遍历所有属性名
            for(var i=0;i<names.length;i++){
                // 根据属性名获取对象该属性的描述对象,描述对象中有configurable,enumerable,writable,value
                var desc=Object.getOwnPropertyDescriptor(source,names[i]);
                // 表述对象的value就是这个属性的值
                // 判断属性值是否不是对象类型或者是null类型
                if(typeof desc.value!=="object" || desc.value===null){
                    // 定义目标对象的属性名是names[i],值是上面获取该属性名的描述对象
                    // 这样可以将原属性的特征也复制了,比如原属性是不可枚举,不可修改,这里都会定义一样
                    Object.defineProperty(target,names[i],desc);
                }else{
                    // 新建一个t对象
                    var t={};
                    // desc.value 就是源对象该属性的值
                    // 判断这个值是什么类型,根据类型创建新对象
                    switch(desc.value.constructor){
                        // 如果这个类型是数组,创建一个空数组
                        case Array:
                            t=[];
                        break;
                        // 如果这个类型是正则表达式,则将原值中正则表达式的source和flags设置进来
                        // 这两个属性分别对应正则desc.value.source 正则内容,desc.value.flags对应修饰符
                        case RegExp:
                            t=new RegExp(desc.value.source,desc.value.flags);
                        break;
                        // 如果是日期类型,创建日期类型,并且把日期值设置相同
                        case Date:
                            t=new Date(desc.value);
                        break;
                        default:
                        // 如果这个值是属于HTML标签,根据这个值的nodeName创建该元素
                            if(desc.value instanceof HTMLElement)
                                t=document.createElement(desc.value.nodeName);
                        break;
                    }
                    // 将目标元素,设置属性名是names[i],设置value是当前创建的这个对象
                    Object.defineProperty(target,names[i],{
                        enumerable:desc.enumerable,
                        writable:desc.writable,
                        configurable:desc.configurable,
                        value:t
                    });
                    // 递归调用该方法将当前对象的值作为源对象,将刚才创建的t作为目标对象
                    cloneObj(desc.value,t);
                }
            }
            return target;
        }




       var o=cloneObj(obj);
       console.log(obj);
       console.log(o);


    //    var arr=[];
    //    var a=new arr.constructor();
    </script>
</body>
</html>

对象深复制(面试重点)

原文:https://www.cnblogs.com/wjsblog/p/12900615.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!