前言
大家好,我是珂圩
深浅拷贝在工作中也经常使用,大家多多少少都有些了解
本章来总结记录一下深浅拷贝的区别和方法,希望对你有所帮助
数据类型的存储方式
首先我们需要了解数据类型
- 基本类型: number,string...
- 引用类型: object
每种类型是如何存储的
基本类型 :保存在栈内存中
引用类型 :保存在堆内存中,然后在栈内存中保存该数据堆内存的索引
浅拷贝
浅拷贝就是指只拷贝了栈内存中的数据 ,也就是说这份数据中存在引用类型的数据,也只是拷贝了该数据在栈内存中的索引
假如我们浅拷贝一份数据后(数据中含有引用类型),再修改拷贝后的数据中的引用类型,此时远数据也会改变
总结一下
- 如果是基本类型就是拷贝基本类型的值
- 如果是引用类型则是拷贝的内存地址
实现一个浅拷贝
js
function shallowClone(obj){
const newObj = {}
for(let prop in obj){
if(obj.hasOwnProperty(prop)){
newObj[porp] = obj[prop]
}
}
return newObj
}
在JavaScript中存在浅拷贝的方法有
object.assign
js
const obj = {...}
const newObj = Object.assign({},obj)
Array.prototype.slice()
js
const arr = [1,2,3]
const newArr = arr.slice(0)
Array.prototype.concat()
js
const arr = [1,2,3]
const newArr = arr.concat(0)
...(扩展运算符)
js
const arr = [1,2,3]
const newArr = [...arr]
深拷贝
深拷贝就是将数据完全拷贝成一个新数据,也就是开了一块新内存在存储数据, 修改拷贝后的新数据老数据也不会变
使用JSON.stringify()
实现简易版的深拷贝,但是其中会存在一些问题,这种方式会忽略 undefined、symbol、function(函数)
js
const obj = {...}
const newObj = JSON.parse(JSON.stringify(obj))
还有一种方式是循环递归来实现深拷贝
js
function cloneDeep (obj,hash = new weakMap()){
if(obj == null) return obj
if(obj instanceof Date) return new Date(obj)
if(obj instanceof RegExp) return new RegExp(obj)
if(typeof obj !== 'object') return obj
if(hash.get(obj)) return hash.get(obj)
let cloneObj = new obj.constructor()
hash.set(obj,cloneObj)
for(let key in obj){
if(obj.hasOwnProperty(key)){
cloneObj[key] = cloneDeep(obj[key],hash)
}
}
return cloneObj
}
结语
如果此文章对你有帮助,点个赞支持一下
后续还会不定时出一些文章或针对某个领域的系列文章
有兴趣的可以关注一下!