对象的深复制

对象的深复制

  • 源对象的属性更改,不会引起复制后的对象个属性的更改
  • 源对象的任何属性与子属性与新对象的之间没有任何引用关系

代码bug正在修复:某些函数的函数名没有copy上,如n对象的value属性所代表的函数

测试用例:

 var obj = {
            a: 1,
            b: "a",
            c: true,
            d: function (a, b) {
                if (a > 10) a = 10;
                if (b > 5) {
                    b = 5;
                } else if (b < 0) {
                    b = 0;
                }
                console.log(a + b);
            },
            e: [1, 2, 3, 4],
            f: {
                g: ["a", "b", "c"],
                h: new Date(),
                i: /^[a-z]+$/g,
                j: {
                    k: {

                    },
                    l: [true, false],
                    m: [
                        { id: 1001, name: "abc1" },
                        { id: 1002, name: "abc2" },
                        { id: 1003, name: "abc3" }
                    ]
                }
            }
        }
        Object.defineProperties(obj.f.j, {
            n: {
                value: function () {
                    console.log("abcd");
                }
            },
            o: {
                value: 10,
                enumerable: true
            },
            p: {
                value: [1, 2, 3],
                writable: true
            },
            q: {
                value: true,
                writable: true,
                enumerable: true
            }
        });


        Object.defineProperties(obj.f.j.k, {
            r: {
                value: function () {

                },
                writable: true
            },
            s: {
                value: { a: 1 },
                enumerable: true
            }
        });
        // console.log(obj);

代码:

var obj1 = cloneObject(obj);
           
            obj.f.j.p[2]=10;
            console.log(obj,obj1);

        function cloneObject(sourceObj, targetObj) {
            // targetObj=targetObj || {};
            if (!targetObj) {
                // sourceObj.constructor就是 sourceObj的类型
                // sourceObj是数组  sourceObj.constructor->Array   new Array();
                targetObj=new sourceObj.constructor();
                switch (sourceObj.constructor) {
                    case RegExp:
                        targetObj=new RegExp(sourceObj.source,sourceObj.flags);
                        break;
                    case Date:
                        targetObj=new Date(sourceObj);
                        break;
                }
            }
            var names = Object.getOwnPropertyNames(sourceObj);
            for (var i = 0; i < names.length; i++) {
                // console.log(names[i],sourceObj[names[i]]);
                // console.log(typeof sourceObj[names[i]]);
                var desc = Object.getOwnPropertyDescriptor(sourceObj, names[i]);
                if (typeof desc.value === "object") {
                    var o = cloneObject(desc.value);
                    Object.defineProperty(targetObj, names[i], {
                        enumerable: desc.enumerable,
                        configurable: desc.configurable,
                        writable: desc.writable,
                        value: o
                    });
                } else if (typeof desc.value === "function") {
                    var fnStr = desc.value.toString().replace(/\n/g, "");
                    var arg = fnStr.match(/\((.*?)\)/)[1];
                    var content = fnStr.match(/{(.*)}/)[1];
                    var fn = new Function(arg, content);
                    Object.defineProperty(targetObj, names[i], {
                        enumerable: desc.enumerable,
                        configurable: desc.configurable,
                        writable: desc.writable,
                        value: fn
                    });
                } else {
                    Object.defineProperty(targetObj, names[i], desc);
                }
            }
            return targetObj;
        }

猜你喜欢

转载自www.cnblogs.com/ltfxy/p/12337059.html