> 文章列表 > JS 中深拷贝的几种爱恨情仇

JS 中深拷贝的几种爱恨情仇

JS 中深拷贝的几种爱恨情仇

页面开发中,经常会碰到需要对数据进行某些处理操作,又不想影响原先的数据,所会经常将数据进行拷贝,当然这里指的是深拷贝。
深拷贝和浅拷贝的区别?
深拷贝通通俗点来讲呢,其实就是不管当前要操作的数据层级有多深,当我们操作深拷贝后的数据的值,不会对原先的值造成影响;
浅拷贝呢,其实就是当数据层级很深时,你在操作拷贝后的数据时,只有第一层的数据进行修改不会影响原来的数据,当你操作二级以上的数据时,依然会对原先的数据造成影响,典型的浅拷贝的方式如:Object.assgin。

1、使用递归的方式实现深拷贝
//使用递归的方式实现数组、对象的深拷贝

function clone(target, map = new WeakMap()) {if (typeof target === "object") {// let cloneData = Object.prototype.toString().call(target)==="[object,Object]"?{}:[]let cloneData = Array.isArray(target) ? [] : {};if (map.get(target)) {return map.get(target);}map.set(target, cloneData);for (let key in target) {// 判断是数组还是对象if (target[key] && typeof target[key] === "object") {cloneData[key] = clone(target[key]);} else {cloneData[key] = target[key];}}return cloneData;} else {return target;}}

2、JSON.parse( JSON.stringify ( 待拷贝对象 ) )

var user = {name: "法医",age: 18,like: {eat: "面条",sport: "篮球",},
};var target = JSON.parse(JSON.stringify(user));
target.like.eat = "米饭";
console.log(user); //{name: '法医', like: {eat: '面条', sport: '篮球'}}
console.log(target); //{name: '法医', like: {eat: '米饭', sport: '篮球'}}

但是这种方式有一个缺点,那就是里面的函数无法被拷贝。

var user = {name: "法医",age: 18,like: {eat: "面条",sport: "篮球",},say:function(){console.log("前端猎手");}
};var target = JSON.parse(JSON.stringify(user));
target.like.eat = "米饭";
console.log(user); //{name: '法医', like: {eat: '面条', sport: '篮球'},say:f()}
console.log(target); //{name: '法医', like: {eat: '米饭', sport: '篮球'}}

3、通过jQuery的extend方法实现深拷贝

var array = [1,2,3,4];
var newArray = $.extend(true,[],array);

4、Object.assign()拷贝

Object.assign(target, ...sources)参数: target--->目标对象source--->源对象返回值:target,即目标对象
var target={name:'guxin',age:25};
var source={state:'single'}
var result=Object.assign(target,source);
console.log(target,target==result);

JS 中深拷贝的几种爱恨情仇
如果只是想将两个或多个对象的属性合并到一起,不改变原有对象的属性,可以用一个空的对象作为target对象。像下面这样:

var result=Object.assign({},target,source);

当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。

5、lodash函数库实现深拷贝
lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝