手写深拷贝(设计思路)
2022-08-18 本文已影响0人
一只程序元
思路:
深拷贝运用到的主要思想是递归思想,主要的思路就是运用递归的思想实现将对象中的所有是引用数据类型的改变成基本数据类型
实现前的知识点准备:
1.基本数据类型和引用数据类型的区别:
基本数据类型包括 Number(数字),String(字符串),Boolean(布尔),Undefined(未定义),Null(空);基本数据类型的赋值就是简单赋值,如果一个变量向另一个变量赋值时,会在变量对象上创建一个新值,然后把这个值复制到为新变量分配的位置上
var a = 1;
var b = a;
a++
console.log(a)//2
console.log(b)//1
/*代码执行过程分析
1、a在内存中保存了1这个值
2、a进行对b的初始化,此时b也保存了1这个值(新开辟的内存空间)
3、a进行+1的操作,然后将最终的值放在自己的内存对应位置中(注意:不会影响b的数据,因为此时b是在另一个内存中,a和b的值是相互独立的,一者改变不会影响到另一个方的值)
*/
引用数据类型也叫做复杂数据类型,主要包括 Object(对象), Array(数组), Function(函数);它们的赋值操作后是会相互影响的
var a = {};
var b = a;
a.name = 'Tom';
console.log(a.name);//Tom
console.log(b.name);//Tom
/*代码执行过程分析
1、a在栈内存中存入这个对象所在的堆内存的对象的地址
2、a对b进行初始化,此时b赋值的是a所在栈内存中的地址
3、在a这个对象中设置name属性,并赋值为 Tom
4、此时因为b赋值的是a的地址,两者所指向的地址相同 故b的值也会随之更改
*/
深拷贝的实现:
1、先对判断数据类型的方法进行封装
// 判断数据类型的函数
function getType(data) {
return Object.prototype.toString.call(data).slice(8, -1);
}
2、判断传入的数据的类型是什么,如果是对象或者数组的话则返回一个新对象或者一个新数组,否则直接返回数据
3、对数据进行遍历,将每条数据进行克隆,在遍历的过程中,若发现要拷贝的数据依然是数组或者对象(引用数据类型)的时候,则用到递归拷贝,直到把数据中所有的引用数据类型转换为基本数据类型
4、返回结果
function deepClone(json) {
// 1. 判断传进来的数据类型 如果是数组创建一个新数组 如果是对象创建一个新对象 其他情况都直接返回
if(getType(json) == 'Object'){
var res = {};
} else if (getType(json) == 'Array'){
var res = [];
} else {
return json;
}
// 2. 把数据在复制存储一次 获取到每个数据
for(var k in json){
// 如果要拷贝的数据 是数组或者对象 需要进行递归拷贝
if(getType(json[k]) == 'Object' || getType(json[k]) == 'Array'){
res[k] = deepClone(json[k]);
} else {
res[k] = json[k];
}
}
// 3. 返回出去
return res;
}