一:根据数据类型拷贝数据
1、基本数据类型:
拷贝后生成一份新的数据,修改拷贝后的数据不会影响原数据
2、引用数据类型:
拷贝后的数据不会生成新的数据,修改拷贝后的数据会影响原数据
注:修改拷贝以后的数据会影响原数据称为浅拷贝,修改拷贝以后的数据不会影响原数据称为深拷贝(又称深度克隆)
二:拷贝数据的方法
拷贝数据主要针对数组和对象两者:
1、使用"="直接赋值给一个变量
将对象/数组直接赋值给一个变量的时候,复制的是对象/数组的地址值,它们指向的都是同一地址值,故赋值之后,修改拷贝之后的数据会影响原数据(浅拷贝)
2、Object.assign(newObj,obj)
使用assign拷贝数据,它底层是通过interator进行遍历的,如果对象/数组中有对象/数组时,那么它赋值的还是地址值,故浅拷贝
3、Array.prototype.concat() // let newArr = arr.concat()
同理assign
4、Array.prototype.slice() // let newArr = arr.slice()
同理assign
5、let newObj = JSON.parse(JSON.stringify(obj))
因为使用JSON.stringify()会将对象/数组变成字符串,所以再使用JSON.parse()转换后,转换的是基本类型,所以在转换后修改数据是不会影响原数据的,故称为深拷贝(深度克隆)
经过本人测试后,整理如下结论:
在使用assign、concat、slice时,如果数组/对象中的元素全部是基本类型(不包含数组/对象)时,那么使用他们拷贝数据的话,就是讲基本类型通过遍历的方式拷贝给新的数组/对象,在修改新的数组/对象中的数据是不会影响原数据(深拷贝);
如果被拷贝的数组/对象中含有数组/对象时,那么在遍历的时候,依然赋值的是对象/数组元素的地址值,故修改新的数组/对象的数据是会影响原数据(浅拷贝)
【使用concat、slice、assign拷贝数据简述:】
修改拷贝后的数组/对象中的数据不含有数组/对象,是深拷贝;
修改拷贝后的数组/对象中的数据含有数组/对象,是浅拷贝。
三:因为浅拷贝会影响原数据,是不安全的,那么该如何解决浅拷贝的风险呢???
//检查数据类型
function checkType(target){
let type = Object.prototype.toString.call(target).slice(8,-)
if(type === 'Null'){
return Null
}else if(type === 'Undefined'){
return Undefinde
}else{
return type
}
}
//深度拷贝数据
function deepClone(target){
let reuslt,type = checkType(target)
if(type === 'Array'){
type = []
}else if(type === 'Object'){
type = {}
}else{
return target
}
for(key in target){
let value = target[key]
if(checkType(value) === 'Array' || checkType(value) === 'Object'){
result[key] = deepClone(value)
}else{
result[key] = value
}
}
return result
}