js 深拷贝 两种

282 阅读1分钟

一·

function deepClone(obj) {          
            if (typeof obj !== "object")  return obj
            if (obj === null)             return null
            if(obj instanceof RegExp)     return new RegExp(obj)
            if (obj instanceof Date)      return new Date(obj)
            
        //=>不直接创建空对象目的:克隆的结果和之前保持相同的所属类
            let deepobj = new obj.constructor
            for (let key in obj) {
       //Object的hasOwnProperty()方法返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。
                if(obj.hasOwnProperty(key))
                deepobj[key] = deepClone(obj[key])
            }
            return deepobj
        }

let deepobj = deepClone(obj)
        deepobj.a = 8
        deepobj.b[0] = 9
        console.log(deepobj);//    { a: 8   b:[9, 3, 4]    c:{d: 5, f: 6}  }
            console.log(obj);//    { a: 8   b:[9, 3, 4]    c:{d: 5, f: 6}  }

二· JSON.stringify先将obj对象转化为JSON字符串,在通过JSON.parse还原对象,这种方法将会在内存中开辟一个新空间来储存对象,所以与原对象互不影响。 弊端: 1、如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。 2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。 3、如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。 4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。 5、JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的, 则使用 JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。 6、如果对象中存在循环引用的情况也无法正确实现深拷贝。

        let deepobj = JSON.parse(JSON.stringify(obj))
       
let obj = {
            a: 1,
            b: [2, 3, 4],
            c: {
                d: 5,
                f: 6
            }
        }
 deepobj.a = 8
 deepobj.b[0]=9
 console.log(deepobj);//    { a: 8   b:[9, 3, 4]    c:{d: 5, f: 6}  }
 console.log(obj);    //    { a: 8   b:[9, 3, 4]    c:{d: 5, f: 6}  }