js实现深拷贝(深度克隆)
对象通过引用被赋值和拷贝。换句话说,一个变量存储的不是“对象的值”,
而是一个对值的“引用”(内存地址)。
因此,拷贝此类变量或将其作为函数参数传递时,所拷贝的是引用,而不是对象本身。
所有通过被拷贝的引用的操作(如添加、删除属性)都作用在同一个对象上。
为了创建“真正的拷贝”(一个克隆),
我们可以使用 `Object.assign` 来做所谓的“浅拷贝”
(嵌套对象被通过引用进行拷贝)或者使用“深拷贝”函数。
浅克隆(浅拷贝)
在数据类型为引用类型的时候,当你给这个变量赋值,其实是引用这个变量在内存中的地址。如下:
var obj = {name: 'ccc', age: 18} // 定义一个变量为对象,引用类型
var cloneObj = obj // 创建一个新变量,并赋值
console.log(cloneObj) // {name: 'ccc', age: 18}
console.log(cloneObj === obj) // true
浅克隆带来的问题:
var obj = {name: 'ccc', age: 18} // 定义一个变量为对象,引用类型
var cloneObj = obj // 创建一个新变量,并赋值
console.log(cloneObj) // {name: 'ccc', age: 18}
console.log(cloneObj === obj) // true
obj.name = 'www'
console.log(cloneObj) // { name: 'www', age: 18 }
我们可以发现,我们修改了obj变量的属性值的时候,cloneObj的属性值也跟着发生了变化。原因是他们虽然是两个变量,但是引用的变量是同一个变量。看下图分析:
image实现深拷贝的三种方法:
1.通过JSON对象实现深拷贝
function deepClone2(obj) {
let _obj = JSON.stringify(obj),
return JSON.parse(_obj);
}
注意: 无法实现对象中方法的深拷贝
image2. 通过Object.assign()拷贝
注意: 当对象只有一级属性为深拷贝;
当对象中有多级属性时,二级属性后就是浅拷贝
image3.递归实现深拷贝
function deepClone(data){
var type = getType(data);
var obj;
if(type === 'array'){
obj = [];
} else if(type === 'object'){
obj = {};
} else {
//不再具有下一层次
return data;
}
if(type === 'array'){
for(var i = 0, len = data.length; i < len; i++){
obj.push(deepClone(data[i]));
}
} else if(type === 'object'){
for(var key in data){
obj[key] = deepClone(data[key]);
}
}
return obj;
}
网友评论