某個專案裡,存在乙個物件陣列,我用lodash
的filter()
函式,分別生成了 a、b 兩個新的物件陣列,但我遍歷了 b 陣列,改造裡面的每乙個物件,沒想到引起 a 陣列的裡物件發生了變化,引發了錯誤。
這是乙個基礎的,對引用型別——物件沒有使用深拷貝的問題,我疏忽了,特此記錄下。
const _ = require('lodash');
let one_brand = [,,
]// 淺拷貝
// 方法一
let two_brand = one_brand.slice(0);
// 方法二(推薦)
let two_brand = _.clone(one_brand)
console.log("改變前:")
console.log(one_brand)
console.log(two_brand)
two_brand[1].count = 0;
console.log("改變後:")
console.log(one_brand)
console.log(two_brand)
return:
改變前:
[ , ]
[ , ]
改變後:
[ , ]
[ , ]
你會發現改變了 two_brand 的乙個物件,one_brand 的那個對應的物件也改變了。這樣不行。
const _ = require('lodash');
let one_brand = [,,
]// 深拷貝
// 方法一
let two_brand = one_brand.map(o => object.assign({}, o));
// 方法二
let two_brand = one_brand.map(o => ());
// 方法三(推薦)
let two_brand = _.clonedeep(one_brand);
console.log("改變前:")
console.log(one_brand)
console.log(two_brand)
two_brand[1].count = 0;
console.log("改變後:")
console.log(one_brand)
console.log(two_brand)
return:
改變前:
[ , ]
[ , ]
改變後:
[ , ]
[ , ]
其實網上還有一種方法:
let two_brand = json.parse(json.stringify(one_brand))
這種方法存在很大的問題。雖然他在 stackoverflow 是得票最多的乙個答案。(
它的主要缺點是,只限於處理可被json.stringify()
編碼的值。
json.stringify()
將編碼 json 支援的值。包含 boolean,number,string,以及物件,陣列。其他任何內容都將被特殊處理。
undefined
,function
,symbol
時,它被忽略掉
infinity
,nan
會被變成 null
date
物件會被轉化為 string (預設呼叫date.toisostring())問:為什麼
json.stringify()
編碼 json 支援的值那麼少呢?因為json是乙個通用的文字格式,和語言無關。設想如果將函式定義也stringify的話,如何判斷是哪種語言,並且通過合適的方式將其呈現出來將會變得特別複雜。特別是和語言相關的一些特性,比如j**ascript中的symbol。
實現乙個深拷貝
第一種 可以使用簡單的方法jsonconst person const copyperson json.parse json.stringify person 修改person內name屬性 person.name che console.log person console.log copyper...
物件陣列的深拷貝和物件的深拷貝
1 對於 普通陣列 陣列元素為數字或者字串 深拷貝很簡單,拷貝之後兩個陣列指標指向的儲存位址不同,從而完成深拷貝 var test 1,2,3 原陣列 var testcopy concat test 拷貝陣列 testcopy 0 4 console.log test 1,2,3 console....
js陣列,物件深拷貝
無事,封裝了乙個js深拷貝的方法 基本思路 deepcopy data data 可能是陣列也可能是物件 1.判斷data是陣列 物件或者其他資料型別 2.宣告空陣列 或者 空物件 res 3.分別處理 如果陣列元素或物件屬性值不是陣列或物件,空陣列或物件之間接收元素 res.push data i...