js深拷贝

2023-11-07

# js深拷贝的几种方式

## 概念介绍

  • 深拷贝:在堆内存中重新开辟一个存储空间,完全克隆一个一模一样的对象;
  • 浅拷贝:不在堆内存中重新开辟空间,只复制栈内存中的引用地址。

本质上两个对象(数组)依然指向同一块存储空间

一、递归方式(推荐,项目中最安全最常用)

function shenClone(obj){
    //判断拷贝的对象是什么类型然后把a赋值成什么类型
        var a = obj instanceof Array?[]:{};
    //遍历对象
        for(let k in obj){
    //如果属性值还是对象模式的话,再进行遍历否则的话直接辅助
            a[k] = typeof obj[k] ==="object"?arguments.callee(obj[k]):obj[k]
        }
    //赋值完毕的话返回a
        return a
    }
    var fn = shenClone(obj);
    console.log(fn);
const copyObj = (obj = {}) => {            //变量先置空
    let newobj = null;  
    //判断是否需要继续进行递归
     if (typeof (obj) == 'object' && obj !== null) {
     newobj = obj instanceof Array ? [] : {};                //进行下一层递归克隆
          for (var i in obj) {
               newobj[i] = copyObj(obj[i])
                }                //如果不是对象直接赋值
            } else newobj = obj;            
            return newobj;    
        }

二、JSON.stringify() ;(这个不推荐使用,有坑)

var fn = JSON.parse(JSON.stringify(arr))
//本质上是通过对象里边不会出现同样的两个键,所以可以通过这种方式

普通的对象也可以进行深拷贝,但是!!!当对象内容项为number,string.boolean的时候,是没有什么问题的。但是,如果对象内容项为undefined,null,Date,RegExp,function,error的时候。使用JSON.stringify()进行拷贝就会出问题了。

三、使用第三方库lodash中的cloneDeep()方法

//需要导入第三方的插件
import lodash from 'lodash';
let obj = {  
	a: {      c: 2,      d: [2, 4, 6],      e:'天气'
    },    
    b: 1}
const newObj = lodash.cloneDeep(obj);obj.b = 20;
console.log(newObj.b);

实际上,cloneDeep()方法底层使用的本来就是递归方法。只是在外层又封装了一层而已。

所以,如果不是原先项目中有使用 lodash 这个库的话,大可不必为了这一个功能而去引入它。

文章上方有提供进行深拷贝的2个函数,推荐使用。

四、jquery的extend()方法进行深拷贝(推荐在JQ中使用)

//这个方法仅适用于JQuery构建的项目


let obj = {  
	a: {      c: 2,      d: [2, 4, 6],      e:'阿巴阿巴'
    },    
    b: 1}
let newObj= $.extend(true, {}, obj1);

总结:

进行深拷贝的方法:

  • 递归函数 (推荐使用,项目中使用的更多,更小,更安全)
  • JSON.stringify() 和JSON.parse() ; (不推荐使用,如果遇到Function,Date等类型的变量容易出现一些意料之外的问题)
  • 第三方库lodash的cloneDeep()方法 (就情况而定,如果项目中原先就有lodash这个第三方库,可以使用,否则还是推荐使用递归函数。不然成本太高。)
  • JQuery的extend()函数 (推荐在JQuery项目中使用,其他项目依然推荐是用递归函数)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js深拷贝 的相关文章