深淺拷貝區(qū)別:
淺拷貝是拷貝一層阁危,深層次的對象級別的就只拷貝引用玛痊;
深拷貝是拷貝多層,每一級別的數(shù)據(jù)都會拷貝出來狂打。
在JS中擂煞,一般賦值語句=表示的只是對象/數(shù)組的引用,屬于淺拷貝菱父,淺拷貝會導致新數(shù)組和舊數(shù)組共用同一塊內存地址颈娜,其中一個數(shù)組變化,另一個數(shù)組也會相應的變化浙宜。以下是我積累的一些關于對象/數(shù)組深拷貝的方法官辽。
一維數(shù)組的拷貝
(1)slice()
arrayObject.slice(start,end)
返回一個新的數(shù)組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素粟瞬。
let arr = ['old', 1, 2, 3, 4];
let new_arr = arr.slice();
new_arr[0] = 'new';
console.log(arr) // ["old", 1, 2, 3, 4]
console.log(new_arr) // ["new", 1, 2, 3, 4]
(2)concat()
arrayObject.concat(arrayX,arrayX,......,arrayX)
方法用于連接兩個或多個數(shù)組同仆。該方法不會改變現(xiàn)有的數(shù)組,而僅僅會返回被連接數(shù)組的一個副本裙品。
該數(shù)組是通過把所有 arrayX 參數(shù)添加到 arrayObject 中生成的俗批。如果要進行 concat() 操作的參數(shù)是數(shù)組,那么添加的是數(shù)組中的元素市怎,而不是數(shù)組岁忘。
let arr = ['old', 1, 2, 3, 4];
let new_arr = arr.concat();
new_arr[0] = 'new';
console.log(arr) // ["old", 1, 2, 3, 4]
console.log(new_arr) // ["new", 1, 2, 3, 4]
(3)Object.assign() 數(shù)組/對象都可
該方法用于將所有可枚舉的屬性的值從一個或多個源對象復制到目標對象。它將返回目標對象区匠。我們可以使用它進行對象的復制干像、合并。
// 復制
let c = Object.assign({}, { a: 'apple' });
console.log(c); // { a: 'apple' }
//合并
let o = {}
let c = Object.assign(o, { a: 'apple' }, { b: 'banana' }, { c: 'cake' } )
console.log(c) // { a: 'apple', b: 'banana', c: 'cake' }
雖然它可以復制對象驰弄,但是 Object.assign() 拷貝的是屬性值麻汰。假如源對象的屬性值是一個指向對象的引用,它也只拷貝那個引用值戚篙。
(4)ES6擴展運算(...)數(shù)組/對象都可
let arr = ["a", "b"] ;
let arrCopy = [...arr];
arrCopy[1] = "c";
arr // => ["a", "b"]
arrCopy // => ["a", "c"]
以上四個個方法 concat五鲫、slice、JSON.stringify岔擂,... 都算是技巧類,可以根據(jù)實際項目情況選擇使用位喂,接下來我們實現(xiàn)多維數(shù)組/對象的深拷貝。
多維數(shù)組的拷貝
(1)封裝方法
let obj1 = {
a: '1',
b: '2',
c: {
d: '3'
},
d: function aa() {}
}
function deepCopy(obj) {
if(typeof obj !== 'object') return;
let newObj = obj instanceof Array ? [] : {};
for(var key in obj) {
if(obj.hasOwnProperty(key)) {
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
let tes=deepCopy(obj1);
console.log(tes)
obj1.c.d=32;
console.log(obj1)
(2)JSON.parse() & JSON.stringify() (推薦)
原理:實現(xiàn)對象的深拷貝(利用JSON.stringify 將js對象序列化(JSON字符串)乱灵,再使用JSON.parse來反序列化(還原)js對象)
let arr = ["a", "b"] ;
let arrCopy = JSON.parse(JSON.stringify(arr));
arrCopy[1] = "c";
arr // => ["a", "b"]
arrCopy // => ["a", "c"]
(3)lodash
使用第三方的庫進行深拷貝:lodash
該函數(shù)庫也有提供_.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