在項目中,常常會用到拷貝。es6
淺拷貝和深拷貝,相信你們都知道區別,可是怎麼去實現呢?微信
我會分享一些項目中常常會用到的一些方法,而後再手寫一個深/淺拷貝的方法。dom
1. Object.assign函數
相信這個不少人都用過,用過就知道,這個在微信端,ie11或更低版本的ie上並不支持。因此咱們就拋棄了這種方法。測試
這種方法也只是淺拷貝,不能知足深拷貝的需求spa
2. 經過es6的擴展運算符...來實現淺拷貝code
let a = { age: 1 } let b = { ...a } a.age = 2 console.log(b.age) // 1
一般,淺拷貝只能解決部分問題。因此咱們來看看深拷貝。對象
3. JSON.parse(JSON.stringify(object))blog
這個方法在項目中用的挺多的。原型鏈
let a = { age: 1, jobs: { first: 'FE' } } let b = JSON.parse(JSON.stringify(a)) a.jobs.first = 'native' console.log(b.jobs.first) // FE
可是該方法有侷限性:
undefined
symbol
本身實現一個深拷貝是很困難的,由於有不少便捷狀況須要考慮。好比原型鏈,dom如何處理。因此我是根據項目實現的一個簡易版的深、淺拷貝。
推薦一個庫: lodash
var isObject = function(obj) { return obj !== null && (typeof obj === "object" || typeof obj === "function") }; var clone = function(obj, deep) { if (!isObject(obj)) { throw new Error(obj + " is not object"); } var newObj; var cloneArray = function(item) { var newItem = []; var size = item.length; for (var i = 0; i < size; i++) { var vk = item[i]; if (deep && isObject(vk)) { newItem[i] = clone(vk, deep); } else { newItem[i] = vk; } } return newItem; }; var cloneObject = function(item) { var newItem = {}; Object.keys(item).forEach(function(n) { var v = item[n]; if (deep && isObject(v)) { newItem[n] = clone(v, deep); } else { newItem[n] = v; } }); return newItem; }; if (obj instanceof Array) { newObj = cloneArray(obj); return newObj; } newObj = cloneObject(obj); return newObj; }
測試代碼:
var obj1 = { a: 1, b: ["a", "b"] }; var obj2 = { b: 2, c: obj1 }; var obj3 = clone(obj2, true); var obj4 = clone(obj2, false); obj1.b = ["a", "b", "c"]; obj1.a = "2"; console.log(obj3); console.log(obj4);
輸出結果:
從結果能夠看出:
深拷貝obj3的結果不會由於引用類型obj1的改變而改變
淺拷貝obj4的結果會由於引用類型obj1的改變而改變