js:深浅拷贝
浅拷贝
首先来看js的浅拷贝:
首先来直观的感受一下什么是拷贝。
let arr = [1, 2, 3];
let newArr = arr;
newArr[0] = 100;
console.log(arr);//[100, 2, 3]
这是直接赋值的情况,不涉及任何拷贝。当改变newArr的时候,由于是同一个引用,arr指向的值也跟着改变。
现在进行浅拷贝:
let arr = [1, 2, 3];
let newArr = arr.slice();
newArr[0] = 100;
console.log(arr);//[1, 2, 3]
当修改newArr的时候,arr的值并不改变。什么原因?因为这里newArr是arr浅拷贝后的结果,newArr和
arr现在引用的已经不是同一块空间啦!
这就是浅拷贝!
但是这又会带来一个新的问题:
let arr = [1, 2, {val: 4}];
let newArr = arr.slice();
newArr[2].val = 1000;
console.log(arr);//[ 1, 2, { val: 1000 } ]
不是已经不是同一块空间的引用了吗?为什么改变了newArr改变了第二个元素的val值,arr也跟着变
了。
这就是浅拷贝的限制所在了。它只能拷贝一层对象。如果有对象的嵌套,那么浅拷贝将无能为力。但幸
运的是,深拷贝就是为了解决这个问题而生的,它能 解决无限极的对象嵌套问题,实现彻底的拷贝。当然,这是我们下一段的重点。 现在先让大家有一个基本的概念。
接下来,来研究一下JS中实现浅拷贝到底有多少种方式?
首先手动实现一个浅拷贝:
var obj={
a:1,
b:2
}
function simpleClone(obj){
var cloneobj={};
for(var i in obj){
cloneobj[i]=obj[i];
}
return cloneobj;
}
这是浅拷贝,一旦对象是这样的:
var objj={
a:1,
b:{
c:3,
d:{
e:5,
f:[1,2,3,4,5]
}
}
}
那么浅拷贝的代码将无能为力,
这时深拷贝就出现了:
首先我们来试一试深拷贝的简易实现:
利用JSON.stringfy()方法和JSON.parse()方法 也就是
JSON.parse(JSON.stringify());
下面我们利用递归的思想来对有多层嵌套的对象进行深拷贝:
function deepClone(obj,cloneobj){
var cloneobj=cloneobj||{};
for(var i in obj){
if(typeof obj[i]==='object'&&obj[i]!=null){
cloneobj[i]=Array.isArray(obj[i])?[]:{};
deepClone(obj[i],cloneobj[i]);
}
else {
cloneobj[i]=obj[i];
}
}
return cloneobj;
}
这个就是递归算法的深拷贝了,不管你对象当中嵌套了多少层,深拷贝都可以返回正确的值和对象!
感谢阅读!