|
项目中有时会需要对引用类型进行比较,如常见的object和array,我们知道,引用类型无法直接使用 == 或=== 取得期待结果,因此需要一个迭代的compare函数转化成原始类型进行比较
在迭代中,我们还要注意的是,对象或者数组中的元素可能是一个任意值——除了原始类型值、object、arrray外,这个值还可能是一个方法、一个DOM对象或者window对象,可能你已经注意到了,有部分引用类型是不能进行迭代的,需要分支判断,代码如下: 复制代码 代码如下: function compare(a,b){ var pt = /undefined|number|string|boolean/, fn = /^(function\s*)(\w*\b)/, cr = "constructor", cn = "childNodes", pn = "parentNode", ce = arguments.callee; if(pt.test(typeof a) || pt.test(typeof b) || a === null || b === null){ return a === b || (isNaN(a) && isNaN(b)); //为了方便,此处假定NaN == NaN } if(a[cr] !== b[cr]){ return false; } switch(a[cr]){ case Date : { return a.valueOf() === b.valueOf(); }; case Function : { return a.toString().replace(fn,'$1') === b.toString().replace(fn,'$1'); //硬编码中声明函数的方式会影响到toString的结果,因此用正则进行格式化 }; case Array : { if(a.length !== b.length){ return false; } for(var i=0;i<a.length;i++){ if(!ce(a[i],b[i])){ return false; } } break; }; default : { var alen = 0, blen = 0, d; if(a === b){ return true; } if(a[cn] || a[pn] || b[cn] || b[pn]){ return a === b; } for(d in a){ alen++ ; } for(d in b){ blen++; } if(alen !== blen){ return false; } for(d in a){ if(!ce(a[d],b[d])){ return false; } } break; }; } return true; } console.log(compare({},{a:1})); //false console.log(compare({a:1},{b:2})); //false console.log(compare({b:2,a:1},{a:1,b:2})); //true console.log(compare({a:function(){return false;},b:2},{a:function(){return false;},b:2})); //true console.log(compare([],[])); //true console.log(compare([2,1],[1,2])); //false console.log(compare(function(){alert(1)},function(){})); //false console.log(compare(function aaa(){alert(1)},function(){alert(1)})); //true console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[1])); //false console.log(compare(document.getElementsByTagName("a")[0],document.getElementsByTagName("a")[0])); //true
|
|