夏日北冰洋

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

做前端开发经常会遇到比较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); 

 

posted on 2016-07-13 20:41  夏日北冰洋  阅读(2897)  评论(0编辑  收藏  举报