關鍵字:
JS、引用、賦值、對象復制、數組復制等
前言:
//獲取基礎參數列表數據 getEditTableData(event) { if(event&&event.length>0){ event.forEach(item=>{ delete item.key }) } this.fieldConfDtos=event; }
今天在用angular做父子組件的一些數據傳遞和處理時發現,子組件通過事件傳給父組件的數據被父組件處理后影響到了子組件。event是子組件傳遞過來的參數,這里父組件刪除item.key后,發現子組件數據的key也沒了。查閱資料后發現是對象數組的引用賦值引起的問題。對象賦值問題踩過幾次坑了,這次就系統地記錄一下。
數據類型:https://www.w3school.com.cn/js/pro_js_value.asp
1、基礎數據類型:null、undefined、number、string、boolean
2、對象類型:Object、array、function、data
簡單結論:基礎數據類型是原始值可以直接賦值、而對象類型是引用賦值只是賦值指針。
解決方法:
根據實際情況使用淺拷貝或深拷貝。這個內容比較復雜和廣泛,根據具體情況選用合適的方法。參考https://www.cnblogs.com/panrui1994/p/9378696.html。
常用方法:
1、Object.assign()
(1)是對象類型(2)對象的屬性沒有引用類型,即都是基礎數據類型。如{name:'lucy',obj:{sexy:'m',age:'18'}},這種數據里的obj還是引用類型,復制后依然是共用內存。(3)其他使用注意事項參考https://blog.csdn.net/u012028371/article/details/77817059
2、迭代遞歸法 for...in
(1)適用范圍為obj和arry,其他特殊類型不行。
// 判斷是否為對象
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
//測試用例
let test = {
num: 0,
str: '',
boolean: true,
unf: undefined,
nul: null,
obj: {
name: '我是一個對象',
id: 1
},
arr: [0, 1, 2],
func: function() {
console.log('我是一個函數')
},
date: new Date(0),
reg: new RegExp('/我是一個正則/ig'),
err: new Error('我是一個錯誤')
}
// 迭代遞歸法:深拷貝對象與數組
function deepClone(obj) {
if (!isObject(obj)) {
throw new Error('obj 不是一個對象!')
}
//判斷傳進來的是對象還是數組
let isArray = Array.isArray(obj)
let cloneObj = isArray ? [] : {}
//通過for...in來拷貝
for (let key in obj) {
cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
}
return cloneObj
}
let result = deepClone(test)
console.log(result)
//我們發現,arr 和 obj 都深拷貝成功了,它們的內存引用已經不同了,但 func、date、reg 和 err 並沒有復制成功,因為它們有特殊的構造函數。
