JavaScript深拷贝与浅拷贝

107 阅读1分钟

浅拷贝

浅拷贝数组

        let arr = [1, 2, 3];

        //第一种
        let arr1 = arr.slice();

        //第二种
        let arr2 = arr.concat();

        //第三种
        let arr3 = [...arr];

        //第四种
        let arr4 = [];
        arr.forEach(e => {
            arr4.push(e);
        });
        
        //第五种
        let arr5 = [];
        for (i = 0; i < arr.length; i++) {
            arr5.push(arr[i]);
        }

浅拷贝对象

        let obj = {
            a: 1,
            b: 2
        }
        
        //第一种
        let obj1 = Object.assign({}, obj);
       
        //第二种
        let obj2 = { ...obj };
        
        //第三种
        let obj3 = {};
        for (let e in obj) {
            obj3[e] = obj[e];
        }
        
        //第四种
        let obj4 = {};
        Object.keys(obj).forEach(e => {
            obj4[e] = obj[e];
        });

深拷贝

  1. 手写递归函数
       var obj = {
            id: 1,
            name: '张三',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        }

        var o = {};

        //封装函数
        function deepClone(newobj, oldobj) {
            for (var k in oldobj) {
                //获取属性值
                var item = oldobj[k];
                //判断属性值属于哪种数据类型
                // 1.判断这个值是不是数组
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepClone(newobj[k], item);
                } else if (item instanceof Object) {
                    //2.判断这个值是不是对象
                    newobj[k] = {};
                    deepClone(newobj[k], item);
                } else {
                    //3.是不是简单数据类型
                    newobj[k] = item;
                }
            }
        }
        deepClone(o, obj);




//下面是另一种递归
function deepClone(obj) {
    let objClone = Array.isArray(obj) ? [] : {};
    if(obj && typeof obj === "object") {
        for(let key in obj) {
            if(obj.hasOwnProperty(key)) {
                if(obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                } else {
                    objClone[key] = obj[key];    
                }
             }
         } 
    }
    return objClone
}

  1. JSON.parse(JSON.stringify())

let arr = [1, 3, {
    username: ' kobe'
}];
let arr1 = JSON.parse(JSON.stringify(arr));

//这种方法虽然可以实现数组或对象深拷贝,但不能处理函数和正则,因为这两者基于JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)了。
//比如下面的例子:
let arr = [1, 3, {
    username: ' kobe'
},function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan'; 
console.log(arr, arr4);


  1. jQuery.extend()方法

//$.extend(deepCopy, target, object1, [objectN])//第一个参数为true,就是深拷贝

var $ = require('jquery');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f); 
// false
  1. 函数库lodash的_.cloneDeep方法

//该函数库也有提供_.cloneDeep用来做 Deep Copy

var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false