页面开发中,经常会碰到需要对数据进行某些处理操作,又不想影响原先的数据,所会经常将数据进行拷贝,当然这里指的是深拷贝。
深拷贝和浅拷贝的区别?
深拷贝通通俗点来讲呢,其实就是不管当前要操作的数据层级有多深,当我们操作深拷贝后的数据的值,不会对原先的值造成影响;
浅拷贝呢,其实就是当数据层级很深时,你在操作拷贝后的数据时,只有第一层的数据进行修改不会影响原来的数据,当你操作二级以上的数据时,依然会对原先的数据造成影响,典型的浅拷贝的方式如: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);
如果只是想将两个或多个对象的属性合并到一起,不改变原有对象的属性,可以用一个空的对象作为target对象。像下面这样:
var result=Object.assign({},target,source);
当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝。
5、lodash函数库实现深拷贝
lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝