现在有很多现成的深度克隆(深拷贝)的工具函数,但是我想学习手写一个,了解一下其中的思路。
思路
经过搜索得知,深度克隆主要用到了递归、类型判断等知识,这里整理一下思路:
肯定比较简陋考虑的东西很欠缺,但是思路应该是这样的^_^
首先判断数据类型,JS中有八种数据类型
number bigint string boolean symbol undefined null object
如果是基础数据类型,就直接返回传进来的参数
如果是数组需要遍历数组
如果是对象需要遍历对象
还有比如map date set等
写代码
编写方法体
如果是其他类型
function deepClone(any){
// 其他类型直接返回
return any;
}
判断数组
function deepClone(any){
// 如果是数组
if(Array.isArray(any)){
let clone = [];
for(let i=0;i<any.length;i++){
clone[i] = deepClone(any[i]);
}
return clone;
}
// 其他类型直接返回
return any;
}
判断map
function deepClone(any){
// 如果是数组
if(Array.isArray(any)){
let clone = [];
for(let i=0;i<any.length;i++){
clone[i] = deepClone(any[i]);
}
return clone;
}
// 如果是map
if(any instanceof Map){
let clone = new Map();
for (const item of any) {
clone.set(deepClone(item[0]),deepClone(item[1]));
}
return clone;
}
// 其他类型直接返回
return any;
}
判断set
function deepClone(any){
// 如果是数组
if(Array.isArray(any)){
let clone = [];
for(let i=0;i<any.length;i++){
clone[i] = deepClone(any[i]);
}
return clone;
}
// 如果是map
if(any instanceof Map){
let clone = new Map();
for (const item of any) {
clone.set(deepClone(item[0]),deepClone(item[1]));
}
return clone;
}
// 如果是set
if(any instanceof Set){
let clone = new Set();
for (const item of any) {
clone.add(deepClone(item));
}
return clone;
}
// 其他类型直接返回
return any;
}
判断date
function deepClone(any){
// 如果是数组
if(Array.isArray(any)){
let clone = [];
for(let i=0;i<any.length;i++){
clone[i] = deepClone(any[i]);
}
return clone;
}
// 如果是map
if(any instanceof Map){
let clone = new Map();
for (const item of any) {
clone.set(deepClone(item[0]),deepClone(item[1]));
}
return clone;
}
// 如果是set
if(any instanceof Set){
let clone = new Set();
for (const item of any) {
clone.add(deepClone(item));
}
return clone;
}
// 如果是date
if (any instanceof Date) {
return new Date(any.getTime());
}
// 其他类型直接返回
return any;
}
完整代码
function deepClone(any){
// 如果是数组
if(Array.isArray(any)){
let clone = [];
for(let i=0;i<any.length;i++){
clone[i] = deepClone(any[i]);
}
return clone;
}
// 如果是map
if(any instanceof Map){
let clone = new Map();
for (const item of any) {
clone.set(deepClone(item[0]),deepClone(item[1]));
}
return clone;
}
// 如果是set
if(any instanceof Set){
let clone = new Set();
for (const item of any) {
clone.add(deepClone(item));
}
return clone;
}
// 如果是date
if (any instanceof Date) {
return new Date(any.getTime());
}
//其他类型.......
// 其他object就用普通的
if(typeof any === "object" && any!==null){
let clone = {};
for (const key in any) {
clone[key] = deepClone(any[key]);
}
return clone;
}
// 如果是其他类型就直接返回
return any;
}
测试效果
let obj = {};
let arr = [];
let a = null;
let b = undefined;
let c = NaN;
let d = 100;
let e = '100';
let f = 100n;
let g = true;
let map = new Map();
map.set("name","小明");
map.set("age",16);
let set = new Set();
set.add(1);
set.add(9);
set.add('王二小');
let date = new Date();
console.log(deepClone(obj) === obj);//false
console.log(deepClone(arr) === arr);//false
console.log(deepClone(a) === a);//true
console.log(deepClone(b) === b);//true undefined只有一个值就是undefined
console.log(deepClone(c) === c);//NaN是number类型,但是它不等于任何数字,包括NaN
console.log(deepClone(d) === d);//true
console.log(deepClone(e) === e);//true
console.log(deepClone(f) === f);//true
console.log(deepClone(g) === g);//true
console.log(deepClone(set) === set);//false
console.log(deepClone(map) === map);//false
console.log(deepClone(date) === date);//false
结语
写的不完善,应该有更高级优雅的写法,我这里知识学习训练