美文网首页
Javascript深拷贝

Javascript深拷贝

作者: 八菜冰 | 来源:发表于2019-04-26 19:14 被阅读0次

    什么是深拷贝

    创建一个新的对象或数组时,将原对象/数组的“值”拷贝,而不是“引用”。

    深拷贝

    1. 数组拷贝
      不存在多层嵌套的情况下,直接for遍历、slice()、concat(),都是可行的。

    2. JSON.parse(JSON.stringify(XXX))

    var a = [
    {  name: ' dadad'  },
    {  age: 18 }
    ];
    var copy_a = JSON.parse(JSON.stringify(a))
    copy_a[0].name = 'ddd'
    console.log(a);//   dadad
    console.log(copy_a);//   ddd
    

    通过JSON.stringify()序列化对象;序列化的作用就是存储对象(对象本身存储的只是一个地址映射,如果断电,对象将不复存在,因此需将对象的内容转换成字符串的形式再保存在磁盘上 ),再通过JSON.parse反序列化,申请新的地址,从而copy了对象。
    但需要注意的是

    • 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象

    • 如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

    • 如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

    • 如果obj中存在循环引用的情况也无法正确实现深拷贝

    1. Object.assign({},XXX)
    var a = {b:undefined,c:NaN,d:'sdsd',e:function(){}}
    var copy_a = Object.assign({},a)
    copy_a.b = 2;
    console.(copy_a);
    

    利用ES6中的Object.assign方法,但是当obj是多层嵌套对象时,对于第一层以外的对象,则依然只是引用。

    var a = {
      name: {
            first: 'sss' ,
      }
    }
    var copy_a = Object.assign({},a)
    copy_a.name.first = '2'
    console.log(a.name.first) //  2
    

    但需要copy的对象只是一层时,用Object.assign显然会比JSON省心许多。

    1. 递归拷贝
      当需要拷贝的对象又是多层嵌套,又有函数等等,此时就需要我们手动写一个递归拷贝。
    function copyFn(obj) {
       if (obj == null) {
            return null
        }
        var result = Array.isArray(obj) ? [] : {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                if (typeof obj[key] === 'object') {
                    result[key] = copyFn(obj[key]);  // 如果是对象,再次调用该方法自身
                } else {
                    result[key] = obj[key];
                }
            }
        }
        return result;
    }
    

    参考文章:
    javascript中的深拷贝和浅拷贝?
    JavaScript 实现复杂对象深拷贝(对象值包含函数)

    相关文章

      网友评论

          本文标题:Javascript深拷贝

          本文链接:https://www.haomeiwen.com/subject/oqwqnqtx.html