深拷贝与浅拷贝
对象拷贝,就是把该对象的属性拷贝到新对象中(主要针对object和array这种复杂对象)
浅拷贝:只是拷贝了基本数据类型的数据,而对于引用的数据类型,只是复制了地址,在新对象中引用型字段发生变化时,原对象会随之发生变化。因为指向同一个内存单元。
深拷贝:是复制一个复杂对象,在内存中另开辟一个内存单元,新对象引用字段的变化不会影响原对象的值。
实现思路以及代码:
1.浅拷贝
就相当于赋值操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var a = [3,2,1];
var b = a;
console.log(b);
</script>
</body>
</html>
2.深拷贝(2种实现)
利用递归
(1)以形参的形式传入obj
(2)声明一个变量来存储拷贝内容
(3)判断obj是否为引用类型
(4)若不是,则进行浅拷贝即直接赋值。若是引用类型,则循环obj中每一项,若有复杂类型则递归调用该函数。
(5)return这个新对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var obj = {
"name":"Tom",
"age":20,
main:{
"a":1,
"b":[1,2,3]
},
fn:function(){
alert("copy");
}
}
function copy(obj){
let newobj = null;
if(typeof(obj)=='object'&&obj!==null){
newobj = obj instanceof Array ? []:{};
for(var i in obj){
newobj[i] = copy(obj[i]);
}
}else{
newobj = obj;
}
return newobj;
}
var a = copy(obj);
a.name = "修改";
a.main.a = 10;
console.log(obj);
console.log(a);
</script>
</body>
</html>
JSON对象的parse和stringify
用JSON.stringify把对象转为字符串,然后用JSON.parse把字符串转为新对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
var obj = {
"name":"Tom",
"age":20,
main:{
"a":1,
"b":[1,2,3]
},
fn:function(){
alert("copy");
}
}
var a = JSON.parse(JSON.stringify(obj));
console.log(obj);
console.log(a);
</script>
</body>
</html>
这种JSON的方法虽然可以拷贝对象,但是它会破坏原型链,且无法拷function属性,上面的运行结果显示拷完之后没有function了。所以推荐使用递归来实现深拷贝。