在复杂数据类型(object
,Array
)中,数据存储在堆内存中,那么对于数据的拷贝就出现了两种情况:拷贝引用和拷贝实例
浅拷贝:拷贝引用,数据存储在同一内存中,进行修改操作会互相影响
深拷贝:重新分配内存,并把源对象的所有属性都进行拷贝,保证拷贝后的对象与源对象是不相干的,操作不会互相影响。
浅拷贝
- 最简单的浅拷贝
var a = {a: 1};
var b = a;
console.log(a === b); // true
b.a = 10;
console.log(a, b); // { a: 10 } { a: 10 }
- 源对象拷贝实例,属性对象拷贝引用
外层对象是拷贝实例,如果属性对象时复杂数据类型时,内层元素拷贝引用。
对源对象直接操作,不会影响另一个对象,但对属性操作时,会影响属性值
常用方法:Array.prototype.slice()
,Array.prototype.concat()
,jQuery
的$.extend({}, obj)
,Object.assign()
。
var arr1 = [1, 2, 3];
var arr2 = arr1.slice();
console.log(arr1 === arr2); // false slice返回新的数组,所以两个不等
arr1[1] = 10;
console.log(arr1, arr2); // [ 1, 10, 3 ] [ 1, 2, 3 ]
var arr3 = [{a: 1}, {b: 2}];
var arr4 = arr3.slice();
console.log(arr3 === arr4); // false
arr4[0].a = 10;
console.log(arr3, arr4); // [ { a: 10 }, { b: 2 } ] [ { a: 10 }, { b: 2 } ]
深拷贝
常见方法:JSON.parse()
,JSON.stringify()
,jQuery
的$.extend(true, {}, obj)
, lodash
的_.cloneDeep
和_.clone(value, true)
。
var arr1 = [1, 2, 3];
var arr2 = JSON.parse(JSON.stringify(arr1));
console.log(arr1 === arr2, arr2); // false [ 1, 2, 3 ]
arr1[1] = 10;
console.log(arr1, arr2); // [ 1, 10, 3 ] [ 1, 2, 3 ]