JavaScript对象深度拷贝算是一个老题,时不时开发中也会遇到,有时顺手再写一个,有时直接百度copy省时省力,,不过遇到问题多了之后,时不时就扩展一下,然后发现了一些有趣好玩的东西,不过他们大多不是最优解决方案,只不过提供了一个应用思路(某数学家:遇到新问题,首先看能不能转化成老问题)。
1.对象比较
大家都清楚,在JavaScript中{***}和{***}用==或===比较结果都是false,因为每个对象分配的地址都是不同的,但有时候我们需要比较两个对象的值是否相等,即希望判断{a:1,b:{c:1}}与{b:{c:1},a:1}相等,由于对象是key:value结构,原则上内部是无序结构,所以想要进行深比较,可以使用广度优先递归一层一层的比,因为key不同则必不等,广度优先理想情况下时间复杂度会更优(具体情况可参考其他博文),而这时候,如何你手边正好有个深度拷贝算法,那么加工一下就能改成对象暴力深排序算法,之后再调用JSON.stringify(obj)转化为字符串,相等则等,不等则不等(我给你讲,正则表达式这东西,我是没考虑的哈)。
show you code:
// 深拷贝+排序
function depthSortObject(obj){
if(obj.constructor !== Object){
return;
}
const newobj = {};
for(const i in obj){
newobj[i] = obj[i].constructor === Object ?
sortObject(depthSortObject(obj[i])) : obj[i];
}
return newobj;
}
// 局部排序对象
function sortObject(obj){
const newObj = {};
const objKeys = Object.keys(obj)
objKeys.sort().map((val) => {
newObj[val] = obj[val];
});
return newObj;
}
console.log(depthSortObject(JSON.stringify({a:1,b:{c:1}}))===depthSortObject(JSON.stringify({b:{c:1},a:1})))
是不是特别暴力···(记得实际开发环境自个儿写或者找更优方案)
2.Mock数据
成熟的Mock的工具推荐大家使用Mock.js,更适合项目开发的还有easyMock、Rap等。这里只是说一下如何魔改深拷贝创造Mock数据(下面是简易版代码,复杂版可以做很多配置,可以前往GitHub查看或下载使用,得亏是自己写同事看到后告诉我有Mock.js,不然看过Mock.js之后我都怀疑自己是抄袭。。。)。
//需要的key与其对应类型
const model = {
cost: 'int',
status: 'string',
lossList: [{
date: 'string',
value: [['int','int']],
}]
};
// 又是深拷贝了
function mockData(obj){
const newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else {
for(const i in obj){
newobj[i] = typeof obj[i] === 'object' ?
mockData(obj[i]) : mock(obj[i]);
}
}
return newobj;
}
function mock(type) {
let data = undefined;
switch(type){
case 'int' :
data = Math.floor(Math.random() * 99999);
break;
case 'float' :
case 'number' :
data = (Math.random() * 99999).toFixed(6);
break;
case 'string' :
data = Math.random().toString(36).substr(2);
break;
default :
data = null;
}
return data;
}
console.log(mockData(model))
简单粗暴的深拷贝融合替换值,你要说这么实现性能好不好,以我的观点来看不是很理想,不过结合应用场景,mock数据传过来的json或object的key不会很复杂,所以实际体验效果是很棒的。
······肯定还有很多黑用法没发现,等我到时候遇到了再补