为什么要进行深拷贝?
这是由于js定义的基础数据类型和复杂数据类型的本质决定的,基础数据类型存储在堆中,拷贝赋值引用的是值,修改拷贝后的值并不会影响原值;复杂数据类型值存储在堆中,引用地址存储在栈中,拷贝赋值的是引用地址,修改拷贝后的值会影响原值。
有时候需要对拷贝的值进行修改,但是又不想影响原来的值,便需要深拷贝。
对象是引用类型。
具体实现
数组的深拷贝
- 利用for循环+push
let arr = [1,2,3,4,5]
let resArr = []
for(let i = 0; i <= arr.length-1; i++) {
resArr.push(arr[i])
}
console.log(resArr) //[1,2,3,4,5]
- 利用slice截取特定范围内容不会影响原数据的方法
slice()方法:①slice()数组和字符串都可用;②arr/str.slice(start[包括],end[不包括]),例如对于上方数组里的arr,执行arr.slice(1,3),从左往右开始第一个元素到第三个元素,截取的是[2,3];③省略end表示截取到末尾;④负数代表从右往左数
let arr = [1,2,3,4]
let resArr = arr.slice(0)
console.log(resArr) //[1,2,3,4]
- 利用concat合并空数组得到一个新数组
let arr = [1,2,3,4]
let resArr = arr.concat()
console.log(resArr) //[1,2,3,4]
- 利用ES6拓展运算符...展开得到一个新数组
let arr = [1,2,3,4]
let resArr = [...arr]
console.log(resArr) // [1,2,3,4]
- JOSN.parse(JSON.stringify(arr))
对象的深拷贝
- JSON.parse(JSON.stringfy())
notice:对象中有function,不能正确深拷贝
let obj = {name: '小明', age: 18}
let newObj = JSON.parse(JSON.stringfy(obj))
- 利用ES6对象的Object.assign()方法
notice:只能针对对象属性为基本类型的情况
let obj = {name: '小明', age: 18}
let obj2 = Object.assign({}, obj)
上面的方法,只能克隆拷贝对象本身的值,而不能克隆继承的值,如果需要保持继承,使用下面方法
let obj = {name: '小明', age: 18}
function cloneObj(originObj) {
let originObjProto = Object.getPrototypeOf(originObj);
return Object.assign(Object.create(originObjProto), originObj)
}
let newObj = cloneObj(obj)
- 利用for循环遍历对象,并判断子属性仍旧为对象时递归,需要时调用,完美克隆对象中的function
function cloneObj(obj) {
if(typeof obj !== 'object') {
return obj;
}else {
let newobj = obj.constructor === Array ? [] : {};
for(let i in obj) {
newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
}
return newobj
}
}
cloneObj(需要深拷贝的obj)
/**
* 数组对象深拷贝
* @param obj
* @returns {*}
*/
export default function cloneObj(obj) {
let str = null
let newobj = obj.constructor === Array ? [] : {}
if (typeof obj !== 'object') {
return
} else if (window && window.JSON) {
str = JSON.stringify(obj) // 系列化对象
newobj = JSON.parse(str) // 还原
} else {
for (var i in obj) {
newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]
}
}
return newobj
}
对象的浅拷贝
const info = {name: "why", age: 18};
const obj = Object.assign({}, info);
info.name = "kobe";