浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值),如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。
深拷贝
实现深拷贝1
function deepClone(source) {
// 判断复制的目标是数组还是对象
const targetSource = Array.isArray(source) ? [] : {}
if(typeof source !=='object') return
// 遍历目标
for(let key in obj){
if(source.hasOwnProperty(key)){
// 如果值是对象,就递归一下
if(source[keys] && typeof source[keys] === 'object'){
targetSource[keys] = Array.isArray(source[keys]) ? [] : {}
targetSource[keys] = deepClone(source[keys])
}else{ // 如果不是,就直接赋值
targetSource[keys] = source[keys]
}
}
}
}
实现深拷贝2
const closeArray = JSON.parse(JSON.stringify(source))
// 注意只能拷贝一些简单的情况:属性的值是简单类型,简单的对象类型,数组 // 如果是undefined,function, sybmbol 会在转换过程中被忽略
浅拷贝:对象是多层次的情况,改变目标对象会改变源对象
浅拷贝1
首层浅拷贝
function shallowClone(source){
let targetSource = Array.isArray(source) ? [] : {}
for(let key in source){
if(source.hasOwnProperty(key)){
targetSource[key] = source[key]
}
}
return targetSource
}
浅拷贝1
const cloneArray = source.slice()
浅拷贝2
const cloneArray = source.slice()
浅拷贝3
const cloneArray = Object.assign({}, source)
- source函数是一个取值的函数,Object.assign不会复制这个取值函数,只会拿到这个值之后,将这个值复制过去
const source = {
get foo() { return a}
}
const target = {}
Object.assign(target,source)
//targrt = {foo: "a"}
浅拷贝4
cosnt cloneArray = {...source}
总结
赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值; JavaScript 中数组和对象自带的拷贝方法都是“首层浅拷贝”; JSON.stringify 实现的是深拷贝,但是对目标对象有要求(非 undefined,function); 若想真正意义上的深拷贝,请递归。