在復(fù)雜數(shù)據(jù)類型(object,Array)中,數(shù)據(jù)存儲(chǔ)在堆內(nèi)存中,那么對(duì)于數(shù)據(jù)的拷貝就出現(xiàn)了兩種情況:拷貝引用和拷貝實(shí)例
淺拷貝:拷貝引用,數(shù)據(jù)存儲(chǔ)在同一內(nèi)存中,進(jìn)行修改操作會(huì)互相影響
深拷貝:重新分配內(nèi)存,并把源對(duì)象的所有屬性都進(jìn)行拷貝,保證拷貝后的對(duì)象與源對(duì)象是不相干的,操作不會(huì)互相影響。
淺拷貝
- 最簡(jiǎn)單的淺拷貝
var a = {a: 1};
var b = a;
console.log(a === b); // true
b.a = 10;
console.log(a, b); // { a: 10 } { a: 10 }
- 源對(duì)象拷貝實(shí)例,屬性對(duì)象拷貝引用
外層對(duì)象是拷貝實(shí)例,如果屬性對(duì)象時(shí)復(fù)雜數(shù)據(jù)類型時(shí),內(nèi)層元素拷貝引用。
對(duì)源對(duì)象直接操作,不會(huì)影響另一個(gè)對(duì)象,但對(duì)屬性操作時(shí),會(huì)影響屬性值
常用方法: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返回新的數(shù)組,所以兩個(gè)不等
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 ]