Java教程

javascript深拷贝三种方法

本文主要是介绍javascript深拷贝三种方法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

方法一: 使用JSON转换

	function deepClone(target) {
	    //通过数据创建JSON格式的字符串
	    let str = JSON.stringify(target);
	    console.log(str);
	    //将JSON字符串转化为JS数据
	    let data = JSON.parse(str);
	    return data;
	}

缺点:

  • JSON不能克隆方法;
  • JSON不能克隆循环引用,如: obj.b.push(obj.c); obj.c.j = obj.b;

方法二: 使用递归

function deepClone3(target) { 
    //检测数据类型
    if (typeof target !== 'object' || target === null) {
        // target 是 null ,或者不是对象和数组,说明是原始类型,直接返回
        return target;
    } else { 
        //创建一个容器,存储数组或者对象
        const result = Array.isArray(target) ? [] : {};
        //遍历target
        for(let key in target) { 
            //检测该属性是否为对象本身的属性(不能拷贝原型对象的属性)
            if(target.hasOwnProperty(key)) { 
            	//递归遍历子元素,直到能返回原始值
                result[key] = deepClone3(target[key]);
            }
        }
        return result;
    }
}
  • 优点: 递归可以克隆方法
  • 缺点: 递归不可以克隆循环引用 如: obj.b.push(obj.c); obj.c.j = obj.b;即b中有c,c中有b,这样递归时会不停执行克隆 b–>c–>b–>c–…

方法三: 递归+映射

首先要明白map.set()这个方法传入的值是按引用传入的,代码如下:

let result = [1,2,3];
const map = new Map();
map.set(0,result)  //这里map.get(0)是[1,2,3]
result.push(4); //这里map.get(0)是[1,2,3,4]
//综上可以得知map.set()方法传入的值是按引用传入

综上可以得知map.set()方法传入的值是按引用传入
接下来解决递归版深拷贝无法拷贝循环引用的问题,代码如下

function deepClone3(target,map = new Map()) { 
    //检测数据类型
    if (typeof target !== 'object' || target === null) {
        // target 是 null ,或者不是对象和数组,说明是原始类型,直接返回
        return target;
    } else { 
        //克隆数据前,先进行判断数据之前是否克隆过
        let cache = map.get(target);
        //如果克隆过,直接返回映射中键对应的值,绕开了递归
        if(cache) { 
            return cache;
        }
        //创建一个容器,存储数组或者对象
        const result = Array.isArray(target) ? [] : {};
        //将新的结果存入到映射中,克隆目标当键,克隆后结果当值
        //注意:map.set()传入的值是按引用传入
        map.set(target,result);
        //遍历target
        for(let key in target) { 
            //检测该属性是否为对象本身的属性(不能拷贝原型对象的属性)
            if(target.hasOwnProperty(key)) { 
                result[key] = deepClone3(target[key],map);
            }
        }
        return result;
    }
}

//测试用例
const obj1 = {
    b:['1','2','3'],
    c: {h: 20}
}
obj1.b.push(obj1.c);   
obj1.c.j = obj1.b;
const obj2 = deepClone3(obj1)

几个丑字加深理解:
在这里插入图片描述

  • 优点: 解决递归无法深拷贝循环引用问题.
这篇关于javascript深拷贝三种方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!