浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个 地址,就会影响到另一个对象。
深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。拷贝前后两个对象互不影响。
javaScript数据类型分为以下两类:
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
有个问题:
为什么要进行深度拷贝呢?直接赋值不可以吗?
值类型是不分什么深拷贝浅拷贝的。
引用数据类型要明白一点,引用数据类型在值传递的时候,传递的是内存地址
var a = [ 1, 2 ]
var b = a
b[1] = 0
console.log(a) //打印结果为[ 0, 2 ]
b = a 是将a的内存地址赋给了b ,此时a和b指向的是同一个内存地址,b值的改变会影响到a
现写一个方法对一个引用数据类型进行深拷贝。(就是一层一层地扒开,一直到值类型,再进行值传递。)
<!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>
<script>
function cloneObj(obj){
if(typeof obj=='object'){
if(obj instanceof Array){
var result = [];
for(var i=0;i<obj.length;i++){
result[i] = cloneObj(obj[i]);
}
return result;
}else{
var result = {};
for(var i in obj){
result[i] = cloneObj(obj[i]);
}
return result;
}
}else{
return obj;
}
}
var obj1 =[12,{a:11,b:22},5]
var obj2 = cloneObj(obj1)
obj2[1].a+=100; //改变obj2,看是否影响到了a
console.log(obj1)
console.log(obj2)
</script>
</body>
</html>
结果: