JavaScript深拷貝與淺拷貝實現(xiàn)詳解
對于基本類型數(shù)據(jù)
可以說都是深拷貝。
對于引用類型數(shù)據(jù)
對于引用類型數(shù)據(jù),淺拷貝 后,因為淺拷貝只拷貝了引用地址,所以兩個對象均使用同一個引用地址,此引用地址指向同一個內存即數(shù)據(jù)值。對其中任何一個對象操作會改變引用地址對應的數(shù)據(jù)的值。
而 深拷貝 將一個對象從內存中完整的拷貝一份出來,從堆內存中開辟一個新的區(qū)域存放新對象,且修改新對象不會影響原對象。
問:解構賦值是深拷貝還是淺拷貝?
若數(shù)組是一維數(shù)組,則可以看做是深拷貝。
let arr = [1, 2, 3] let copyArr = [...arr] copyArr.push(4) console.log(arr, copyArr)
若數(shù)組是多維數(shù)組,則是淺拷貝。
let arr2 = [[1, 2, 3], [9, 0, 6]] let copyArr2 = [...arr2] copyArr2[0].push(77) console.log(arr2, copyArr2)
注: 簡單賦值只是復制了引用地址:
const a1 = [1, 2]; const a1Copy = a1; a1Copy[0] = 9; console.log(a1) // [9, 2] console.log(a1Copy) // [9, 2]
若不用 擴展運算符拷貝, ES5 中用變通方法來拷貝數(shù)組
const a1 = [1, 2]; const a1Copy = a1.concat(); a1Copy[0] = 9; a1 // [1, 2]
實現(xiàn)深拷貝
簡單版
在不使用第三方庫的情況下,想要深拷貝一個對象
const newObj = JSON.parse(JSON.stringify(oldObj))
局限性:
- 無法實現(xiàn)對RegExp、Date、Set、Map等特殊對象的克隆
- 無法拷貝函數(shù)
- 會拋棄對象的constructor,所有的構造函數(shù)會指向Object
- 對象有循環(huán)引用,會報錯
夠用版
使用遞歸,拷貝數(shù)組或對象。
function deepClone(source) { // 定義結果對象或數(shù)組 const targetObj = source.constructor === Array ? [] : {} // 遍歷key for (let keys in source) { // 如果key是對象的自有屬性 // hasOwnProperty()查找一個對象是否有某個屬性,但是不會去查找它的原型鏈。 if (source.hasOwnProperty(keys)) { // 如果是引用類型 if (source[keys] && typeof source[keys] === 'object') { // 遞歸 targetObj[keys] = deepClone(source[keys]) } else { // 如果是基本類型 targetObj[keys] = source[keys] } } } return targetObj }
- 關于其他情況,如解決循環(huán)引用、拷貝特殊對象、拷貝函數(shù)的情況不常見,本文就不寫解決這些問題的代碼啦。
- 在實際開發(fā),克隆數(shù)據(jù)還是使用第三方庫更好。
新發(fā)現(xiàn)個原生深拷貝的方法,
structuredClone
全局的 structuredClone() 方法使用結構化克隆算法將給定的值進行深拷貝 。
適用 H5;
Error 以及 Function 對象是不能被結構化克隆算法復制等等缺點。
詳情看 MDN:傳送門
let obj = { a: [1, 2], b: "eee", c: 3, }; let cloneObj = structuredClone(obj); cloneObj.a[0] = 10; console.log(cloneObj.a[0]); // 10 console.log(obj.a[0]); // 1
到此這篇關于JavaScript深拷貝與淺拷貝實現(xiàn)詳解的文章就介紹到這了,更多相關JS深拷貝與淺拷貝內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
開源免費天氣預報接口API及全國所有地區(qū)代碼(國家氣象局提供)
這篇文章主要介紹了開源免費天氣預報接口API及全國所有地區(qū)代碼(國家氣象局提供)的相關資料,需要的朋友可以參考下2016-12-12BootStrap Table后臺分頁時前臺刪除最后一頁所有數(shù)據(jù)refresh刷新后無數(shù)據(jù)問題
這篇文章主要介紹了BootStrap Table后臺分頁時前臺刪除最后一頁所有數(shù)據(jù)refresh刷新后無數(shù)據(jù)問題,需要的朋友可以參考下2016-12-12JavaScript變量聲明var,let.const及區(qū)別淺析
這篇文章主要介紹了JavaScript變量聲明var,let.const及區(qū)別淺析,需要的朋友可以參考下2018-04-04詳解JavaScript私有類字段和TypeScript私有修飾符
這篇文章主要介紹了JavaScript私有類字段和TypeScript私有修飾符,對私有類感興趣的同學,可以參考下2021-04-04JavaScript中的執(zhí)行環(huán)境和作用域鏈
這篇文章主要介紹了JavaScript中的執(zhí)行環(huán)境和作用域鏈,幫助大家更好的理解和學習JavaScript,感興趣的朋友可以了解下2020-09-09JavaScript實現(xiàn)圖片懶加載(Lazyload)
這篇文章主要介紹了JavaScript實現(xiàn)圖片懶加載(Lazyload)的相關資料,需要的朋友可以參考下2016-11-11微信小程序 scroll-view 水平滾動實現(xiàn)過程解析
這篇文章主要介紹了微信小程序 scroll-view 水平滾動實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-10-10