js浅拷贝和深拷贝

73 阅读2分钟

概念

  • 浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

  • 深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。

实现

  • 浅拷贝
  1. Object.assign( )
let obj1 = {id:1,info:{name:'11',age:10}}
let obj2 = Object.assign({},obj1)
obj2.id = 2 //obj1:{id:1,info:{name:'11',age:10}}
obj2.info.age = 12 //obj1:{id:1,info:{name:'11',age:12}}
//当对象只有一层时,是深拷贝,否则为浅拷贝
  1. ...扩展运算符
let obj1 = { name: 'Kobe', address:{x:100,y:100}}
let obj2= {... obj1}
obj1.address.x = 200;
obj1.name = 'wade'
//obj2 { name: 'Kobe', address: { x: 200, y: 100 } }
//当对象只有一层时,是深拷贝,否则为浅拷贝
  1. Array.prototype.slice()
let arr = [1, 3, {
    username: ' kobe'
    }];
let arr3 = arr.slice();
arr3[2].username = 'wade'
console.log(arr); // [ 1, 3, { username: 'wade' } ]
  1. Array.prototype.concat()
let arr = [1, 3, {
    username: 'kobe'
    }];
let arr2 = arr.concat();    
arr2[2].username = 'wade';
console.log(arr); //[ 1, 3, { username: 'wade' } ]
  1. lodash的_.clone方法
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.clone(obj1);
console.log(obj1.b.f === obj2.b.f);// true
  • 深拷贝
  1. JSON.parse(JSON.stringify())
let arr = [1, 3, {
    username: ' kobe'
}];
let arr1 = JSON.parse(JSON.stringify(arr));
arr1[2].username = 'duncan'; 
//arr:[1,3,{username:'kobe'}] arr1:[1,3,{username:'duncan'}]
  1. 递归
function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

const target = {
    id:1,
    data: [2, 4, 8]
};
const value;
value = clone(target) //value:{id:1,data:[2,4,8]}
target.id = 2 //target:{id:2,data:[2,4,8]}  value:{id:1,data:[2,4,8]}
  1. lodash的_.cloneDeep方法
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
  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