用原生JS实现深拷贝

Posted 小姚同学要继续加油呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用原生JS实现深拷贝相关的知识,希望对你有一定的参考价值。

用原生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]并没有被影响,从而实现了深拷贝。

以上是关于用原生JS实现深拷贝的主要内容,如果未能解决你的问题,请参考以下文章

JS 原生方法原理探究如何实现浅拷贝和深拷贝?

用JSON.stringify去实现深拷贝的弊端

面试之JS深拷贝的实现

面试之JS深拷贝的实现

js实现深拷贝

深浅拷贝