深浅拷贝 详解
1.浅拷贝的方法
-
=
-
直接赋值改变其中的一个数组另一个数组也会变
let arr1=[1,2,3,4] let arr2=arr1; arr1[0]=9; console.log(arr1);//[9, 2, 3, 4] console.log(arr2);// [9, 2, 3, 4]
-
-
-
let obj = { people:{ age:20 } } let p = Object.assign({},obj) p.people.age=30; console.log(p.people.age);//30 console.log(obj.people.age);//30
-
-
{...arr}
-
es6中的数组解构赋值来拷贝
let arr = [ { age:20 },{ name:'李四' } ] let arr1={...arr}; arr1[1].name="张三" console.log(arr[1].name);// 张三 console.log(arr1[1].name);// 张三
-
-
concat
-
利用数组自带的方法 Array.prototype.concat()
let arr = [ { age:20 },{ name:'李四' } ] let arr1={...arr}; arr1[1].name="张三" console.log(arr[1].name);// 张三 console.log(arr1[1].name);// 张三
-
-
slice
-
数组的截取方法
let arr = [ 1,3, { age:20 } ] let arr1 = arr.slice() arr1[2].age=30; console.log(arr[2].age); //30 console.log(arr1[2].age); //30
-
注意:关于Array的slice和concat方法的补充说明:Array的slice和concat方法不修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
原数组的元素会按照下述规则拷贝:
如果该元素是个对象引用(不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。 对于字符串、数字及布尔值来说(不是 String、Number 或者 Boolean 对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。
例如:
let arr = [
1,3,
{
age:20
}
]
let arr1 = arr.slice()
arr1[0]=2;
console.log(arr[0]);//1
console.log(arr1[0]);//2
2.深拷贝方法
-
JSON.parse(JSON.stringify())
-
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数
let arr = [ { age:20 },{ name:'李四' } ] let arr1=JSON.parse(JSON.stringify(arr)); arr1[1].name="张三" console.log(arr[1].name);// 李四 console.log(arr1[1].name);// 张三
-
-
手写递归方法
-
递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝
let arr = [ {name:'li'}, {age:12}, ()=>{return 4} ] let arr1 = deepClone(arr)//调用函数克隆 console.log(arr1[2]);//()=>{return 4} 可以克隆函数 console.log(arr === arr1);//false 因为深克隆引用地址不同 arr1[0].name = "张三" console.log(arr[0].name);// li console.log(arr1[0].name);// 张三 // 获取对象的类型 function getObjType(target) { return Object.prototype.toString.call(target).slice(8, -1) } // 执行深克隆 function deepClone(data) { var type = getObjType(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; };
-
不停学习,热爱是源源不断的动力。