js实现深拷贝、浅拷贝和完美拷贝封装 JSON拷贝和 assign 拷贝的区别

JSON.parse(JSON.stringify()) 和 Object.assign 的区别

Object.assign  浅拷贝 (拷贝一层)

    var obj ={
        name:'张珊',
        age:16,
        list:{a:'我我哦'}
    }
    // var o = obj ;
    // Object.assign  浅拷贝 拷贝一层
    var o =Object.assign({},obj) ;
    o.list.a='李四'
    console.log(o,obj)

控制台输出结果

JSON.parse(JSON.stringify())   深拷贝 多层


    // JSON.parse(JSON.stringify())   深拷贝 多层
    var obj ={
        name:'张珊',
        age:16,
        list:{a:'我我哦'}
    }
    var o = JSON.parse(JSON.stringify(obj)) ;
    o.list.a='李四'
    console.log(o,obj)

控制台输出结果

而我们在平常工作中使用JSON.parse(JSON.stringify()) 就可以解决90%的数据拷贝问题,如果还解决不了,下面有一个近乎完美的深拷贝解决方案可以拿去使用 

    // 完美的深拷贝  封装
    function deepCopy(obj, parent = null) {
    // 创建一个新对象
    let result = {};
    let keys = Object.keys(obj),
        key = null,
        temp= null,
        _parent = parent;
    // 该字段有父级则需要追溯该字段的父级
    while (_parent) {
        // 如果该字段引用了它的父级则为循环引用
        if (_parent.originalParent === obj) {
            // 循环引用直接返回同级的新对象
            return _parent.currentParent;
        }
        _parent = _parent.parent;
    }
    for (let i = 0; i < keys.length; i++) {
        key = keys[i];
        temp= obj[key];
        // 如果字段的值也是一个对象
        if (temp && typeof temp=== 'object') {
            // 递归执行深拷贝 将同级的待拷贝对象与新对象传递给 parent 方便追溯循环引用
            result[key] = deepCopy(temp, {
                originalParent: obj,
                currentParent: result,
                parent: parent
            });
        } else {
            result[key] = temp;
        }
    }
    return result;
}
var obj1 = {
    x: 1, 
    y: 2,
    list:{a:'aa'},
    b:'',
    c:undefined
};
// obj1.z = obj1;
var obj2 = deepCopy(obj1);
// obj1.z =222;
// var obj2 = JSON.parse(JSON.stringify(obj1)) ;    如果用JSON拷贝会丢失undefined(没有意义的值)
obj1.list.a =222;
obj1.b=undefined
console.log(obj1); //太长了去浏览器试一下吧~ 
console.log(obj2); //太长了去浏览器试一下吧~ 

猜你喜欢

转载自blog.csdn.net/weixin_44360943/article/details/108654547