标签:
做前端开发经常会遇到比较js对象是否相等的情况, 或者说其它问题往往会归结到这个问题上来:比如对象数组的去重复。
网上看到过很多例子, 但是基本上都是那种比较简单的对象结构, 而复杂的对象结构,比如对象嵌套对象的情况,还没找到什么直接可以用的代码。
所以今天,就花了点时间写了一个函数实现这个功能, 也是方便自己日后使用, 当然也可以供大家参考。
注释: 目前这个方法只适用于对象的属性是基本类型和对象类型, 数组类型暂时还没考虑, 后面有时间写一个全的。----所以说下面的方法相当于比较两个树
第一个方法: 主要是将对象当做一个树, 通过递归遍历,将对象的所有属性当做节点保存在二维数组中。(这个方法也适用于任何树形数据结构的遍历)
1 /* 2 * 递归方式将obj的所有树路径规整到二维数组中,第一维度表示路径个数,第二个维度表示每条路径上的节点 3 * 返回的是这个二维数组 4 */ 5 function getObjKeyPath(pathArry, paths, obj){ 6 for(var key in obj){ 7 var type = obj[key].constructor.name; //获取属性值对应的类型 8 if(type == "Object"){ 9 if(!paths){ 10 paths = []; 11 } 12 paths.push(key); 13 getObjKeyPath(pathArry, paths, obj[key]); 14 }else{ 15 if(!paths){ 16 pathArry.push([key]); 17 }else{ 18 var arry = paths.concat();//目的是复制数组 19 arry.push(key); 20 pathArry.push(arry); 21 } 22 } 23 } 24 return pathArry; 25 }
第二个方法就是实际的比较函数:
输入参数就是两个对象, 返回true表示两个对象完全相等,反之不等.
主要想法就是,用上面的函数获取到两个对象的属性树, 然后以“叶子节点多的对象作为大树”, 依次取大树的叶子节点路径在小数上的对应值, 一旦取不到或者取到不相等则两个对象肯定不相等。
1 function CompareObj(obj1, obj2){ 2 var keys1 = getObjKeyPath([], null, obj1); 3 var keys2 = getObjKeyPath([], null, obj2); 4 var bigObj = null; 5 var smallObj = null; 6 var keys = null; 7 if(keys1.length >= keys2.length){ 8 bigObj = obj1; 9 smallObj = obj2; 10 keys = keys1; 11 }else{ 12 bigObj = obj2; 13 smallObj = obj1; 14 keys = keys2; 15 } 16 for(var i in keys){ 17 var val1 = bigObj; 18 var val2 = smallObj; 19 for(var j in keys[i]){ 20 var key = keys[i][j]; 21 val1 = val1[key]; 22 val2 = val2[key]; 23 if(val2 == undefined){ 24 return false; 25 } 26 } 27 if(val1 != val2){ 28 return false; 29 } 30 } 31 return true; 32 }
调用就很简单了:
1 var flag = CompareObj(obj1, obj2);
标签:
原文地址:http://www.cnblogs.com/ppneo/p/5668157.html