![e8bb958fcedea2c63bfe3c1b3fbba29a.png](https://i-blog.csdnimg.cn/blog_migrate/f934f78ff3b904d564aff8884dcd01c5.jpeg)
目录
- 1、深拷贝背景
- 2、一层深拷贝(数组、对象)
- 3、多层深拷贝
一、深拷贝背景
我们需要得到一份新的data,增删改查操作都不会影响原始数据。请问如何实现,如下
var arr = [
{ number: 1 },
{ number: 2 },
{ number: 3 }
];
var newarr = arr;
newarr[0]=1;
console.log(arr,newarr)
![3875abba0d6832525574a91077db8df5.png](https://i-blog.csdnimg.cn/blog_migrate/4e78df47a7a445a51ed239f93e594e20.jpeg)
原因是因为应用类型的赋值,只是修改了指针的指向 。可查MDN数据类型
二、数组的一层拷贝
- slice
- concat
- [...]
- 循环
var arr = [1,2,3];
var arr1,arr2,arr3;
arr1 = arr.slice(0);
arr2 = arr.concat();
arr3 = [...arr];
arr[0]=100;
console.log(arr,arr1,arr2,arr3);
二.一、对象的一层拷贝
- Object.assign
- {...}
var obj ={
name:'zh',
age:30
}
var obj1,obj2;
obj1 = Object.assign({},obj);
obj2 = {...obj};
obj.name = '你全家都叫zh'
console.log(obj,obj1,obj2);
三、多层深拷贝
思路:
- 非Object类型,直接赋值
- 递归目标对象的每一项
// 深拷贝
var array = [
{ number: 1 },
{ number: 2 },
{ number: 3 }
];
function shencopy(obj){
if(typeof obj !== 'object'){
return obj
}
var res = Array.isArray(obj)?[]:{};
for(let i in obj){
res[i] = shencopy(obj[i]);
}
return res
}
console.log(shencopy(array));
PS:涉及知识点
1、基本数据类型、应用类型 MDN
![a306f6975602518c15bf92ae54516e8f.png](https://i-blog.csdnimg.cn/blog_migrate/6c18f7f40e2cfce82f1bd67970457699.jpeg)
2、typeof返回 MDN
![32402e0e1326b23c15e46f63b9bdbae6.png](https://i-blog.csdnimg.cn/blog_migrate/8aebf87c4421623dc7810e984cc99b3b.jpeg)
3、数组、对象判断
var arr = [1,2,3];
var obj = {
name:'zh'
}
//方法一 constructor
obj.constructor === Object
arr.constructor === Array
// 方法二 instanceof
arr instanceof Array
obj instanceof Object
//方法三 Object.prototype.toString
Object.prototype.toString.call(arr) === "[object Array]"
Object.prototype.toString.call(obj) === "[object Object]"
// 方法四 Array.isArray
Array.isArray(arr)
4、Object.prototype.toString.call()引发的思考 查看
为什么判断对象、数组要用Object的toString 而不用别的toString?
5、for in / for of
for...in
语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。for...of
语句在可迭代对象(包括Array
,Map
,Set
,String
,TypedArray
,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句