1、总结
- 浅拷贝和深拷贝都是用于对象拷贝的,区别在于浅拷贝是复制对象地址的,只要数据改变,原对象数据会跟着改变;而深拷贝是复制数据,再新建一个地址,数据改变不会影响原对象的数据,深拷贝有两种方法,一种是JSON转换,另一种是用递归方法复制对象数据,推荐用JSON转换,方便快捷,就是这么简单。
2、浅拷贝
- 拷贝的是地址,修改拷贝后的数据对原对象有影响
<script>
/*
1、浅拷贝:拷贝的是地址,修改拷贝后的数据对原对象有影响
2、深拷贝:拷贝的是数据,修改拷贝后的数据对原对象没有影响
*/
var obj = {
name: 'jasmine',
age: 18,
hobby: ['画画', '唱歌'],
friend: {
name: 'qiqi',
age: 18
}
}
// 3、浅拷贝
var obj1 = obj;
obj.name = 'jasmine1';
console.log(obj); // jasmine1
console.log(obj1); // jasmine1
</script>
3、深拷贝
- 拷贝的是数据,重新创建一个地址,修改拷贝后的数据对原对象没有影响
4、深拷贝有两种方法(JSON和递归)
JSON:
- let json = JSON.stringify(obj);
- obj1 = JSON.parse(json);
// 4、深拷贝,有两种拷贝方法
// 4.1、第一种方法:用json转换
// 4.2、第二种方法:递归
var obj = {
name: 'jasmine',
age: 18,
hobby: ['画画', '唱歌'],
friend: {
name: 'qiqi',
age: 18
}
}
// 把对象转为JSON格式的字符串,自动进行深拷贝
let json = JSON.stringify(obj);
console.log(json);
// 再把JSON格式的字符串转为对象
obj1 = JSON.parse(json);
obj1.name = "jasmine";
console.log(obj1); // jasmine
递归:
- 用for循环遍历数据,把数据添加到新的对象中,如果里面有引用类型数据,则要用到递归。
- 不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面
- 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可
- 相对于递归,用JSON格式转换会方便很多
// 4.2、第二种方法:递归,把所有的属性添加到新的对象中
// 如果里面有引用类型数据(数组、对象),
// 则不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面
// 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可
// 相对于递归,用JSON格式转换会方便很多
function copy(newObj, obj) {
for (let i in obj) {
// 判断是不是数组类型
if (obj[i] instanceof Array) {
// 声明一个空数组,然后拷贝数组里面的数组
newObj[i] = [];
copy(newObj[i], obj[i]);
// 判断是不是数组类型
} else if (obj[i] instanceof Object) {
// 声明一个空数组,然后拷贝对象里面的数组
newObj[i] = {};
copy(newObj[i], obj[i]);
} else {
newObj[i] = obj[i];
}
}
}
obj1 = {};
copy(obj1, obj);
obj1.hobby[0] = '插画';
console.log(obj1);
5、源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
/*
1、浅拷贝:拷贝的是地址,修改拷贝后的数据对原对象有影响
2、深拷贝:拷贝的是数据,修改拷贝后的数据对原对象没有影响
*/
var obj = {
name: 'jasmine',
age: 18,
hobby: ['画画', '唱歌'],
friend: {
name: 'qiqi',
age: 18
}
}
// 3、浅拷贝
var obj1 = obj;
obj.name = 'jasmine1';
console.log('原对象:')
console.log(obj); // jasmine1
console.log('浅拷贝:')
console.log(obj1); // jasmine1
// 4、深拷贝,有两种拷贝方法
// 4.1、第一种方法:用json转换
// 把对象转为JSON格式的字符串,自动进行深拷贝
let json = JSON.stringify(obj);
console.log('转为JSON字符串:')
console.log(json);
// 再把JSON格式的字符串转为对象
obj1 = JSON.parse(json);
obj1.name = "jasmine";
console.log('深拷贝(JSON):')
console.log(obj1); // jasmine
// 4.2、第二种方法:递归,把所有的属性添加到新的对象中
// 如果里面有引用类型数据(数组、对象),
// 则不能直接拷贝地址,要声明一个空数组然后遍历对象数组,把里面的元素添加到新的数组里面
// 对象也是一样的,创建一个新的对象,然后把对象的数据放到里面即可
// 相对于递归,用JSON格式转换会方便很多
function copy(newObj, obj) {
for (let i in obj) {
// 判断是不是数组类型
if (obj[i] instanceof Array) {
// 声明一个空数组,然后拷贝数组里面的数组
newObj[i] = [];
copy(newObj[i], obj[i]);
// 判断是不是数组类型
} else if (obj[i] instanceof Object) {
// 声明一个空数组,然后拷贝对象里面的数组
newObj[i] = {};
copy(newObj[i], obj[i]);
} else {
newObj[i] = obj[i];
}
}
}
obj1 = {};
copy(obj1, obj);
obj1.hobby[0] = '插画';
console.log(obj1);
</script>
</html>