用原生JS实现深拷贝
浅拷贝和深拷贝的概念这里不做赘述。
深拷贝实现方法有两种
一种是通过JSON.parse(JSON.Stringify(arr))
;
另一种则是通过递归
,本文主要讲述通过递归实现JS的深拷贝。
弊端:都不能实现对于内部函数的拷贝。
通过JSON.parse(JSON.Stringify(arr))实现
var arr = [1,4,{
name:'yzk',age:20}];
//实现深拷贝
var arr2 = JSON.parse(JSON.stringify(arr));
arr2[2].name='zd';
console.log(arr1,arr2)
通过递归实现
思路:
当拷贝的元素不是基础类型时,他只会进行浅拷贝。 赋值的时候(如var a =b),若其是基础类型(b是基础类型(ex:Boolean、String、Number)),则会重新用这个基础类型的值对其进行初始化(不会对其源头有影响)。
//原理理解
var a = 12;
var b = a;
console.log(a,b);//12,12
b=6;
console.log(a,b);//12,6
深拷贝代码实现
<script>
function checkedType(target){
//实现对于每个参数的类型判定,若对这段代码不清楚,
//则把checkedType中的注释去掉看看执行结果即可理解。
// var arr = []
// var obj ={}
// var x = null
// console.log(Object.prototype.toString.call(arr)); //[object Array]
// console.log(Object.prototype.toString.call(obj)); //[object Object]
// console.log(Object.prototype.toString.call(null)); //[object Null]
return Object.prototype.toString.call(target).slice(8,-1)
}
//实现深度克隆
function clone(target) {
// 判断拷贝的数据类型
// 初始化变量result 成为最终克隆的类型
let result, targetType = checkedType(target);
if (targetType === 'Object') {
result = {
};
} else if (targetType === 'Array') {
result = [];
} else {
return target;
}
// 遍历目标数据
for(let i in target){
// 获取遍历数据结构的每一项
//通过target[i]的方法:无论对象的属性还是数组的属性都能访问
let value = target[i];
if(checkedType(value)==='Object'||checkedType(value)==='Array'){
// 继续遍历获取到的value值
result[i] = clone(value);
}else {
result[i] = value;
}
}
return result;
}
var arr1 = [1,3,5,{
name:'yzk',age:20}];
var arr2 = clone(arr1);
console.log(arr1,arr2);
console.log('---------');
arr2[3].name = 'zd';
console.log(arr1,arr2);
</script>
输出结果
当改变arr2中的arr2[3]对象的数据时,原来的arr1中的arr[3]并没有被影响,从而实现了深拷贝。