js中判断Object、Array、Function等引用类型对象是否相等

 更新时间:2012年08月29日 00:14:10   作者:  
项目中有时会需要对引用类型进行比较,如常见的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

相关文章

  • JS控制伪元素的方法汇总

    JS控制伪元素的方法汇总

    本文给大家介绍js控制伪元素的方法汇总,本文涉及到获取伪元素属性值的方法,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起学习吧
    2016-04-04
  • javascript实现相同事件名称,不同命名空间的调用方法

    javascript实现相同事件名称,不同命名空间的调用方法

    这篇文章主要介绍了javascript实现相同事件名称,不同命名空间的调用方法,涉及javascript命名空间及事件调用的技巧,需要的朋友可以参考下
    2015-06-06
  • js实现无感刷新的实践(附前后端实现)

    js实现无感刷新的实践(附前后端实现)

    无感刷新机制的目的是在用户不知情的情况下,自动更新其认证令牌本文,主要介绍了js实现无感刷新的实践(附前后端实现),具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • chorme 浏览器记住密码后input黄色背景处理方法(两种)

    chorme 浏览器记住密码后input黄色背景处理方法(两种)

    使用chrome浏览器选择记住密码的账号,输入框会自动加上黄色的背景,有些设计输入框是透明背景的,需要去除掉这个黄色的背景。下面给大家分享chorme 浏览器记住密码后input黄色背景处理方法,一起看看吧
    2017-11-11
  • layui的布局和表格的渲染以及动态生成表格的方法

    layui的布局和表格的渲染以及动态生成表格的方法

    今天小编就为大家分享一篇layui的布局和表格的渲染以及动态生成表格的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • Highcharts 非常实用的Javascript统计图demo示例

    Highcharts 非常实用的Javascript统计图demo示例

    官网实例中给出了各式各样的demo,可以参照document修改自己需要的即可,本文实现的是一个学生成绩走势demo,有需求的朋友可以参考下哈,希望对大家有所帮助
    2013-07-07
  • js猜数字小游戏的简单实现代码

    js猜数字小游戏的简单实现代码

    这篇文章介绍了js猜数字小游戏的简单实现代码,很好玩的游戏哦,可以看看你的智商 是否惊人额
    2013-07-07
  • javascript实现倒计时效果

    javascript实现倒计时效果

    这篇文章主要为大家详细介绍了javascript实现倒计时效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • JS中promise化微信小程序api

    JS中promise化微信小程序api

    这篇文章主要给大家通过代码实例分析了promise化微信小程序api的使用方法,对此有需要的朋友可以参考学习下。
    2018-04-04
  • JavaScript如何使用插值实现图像渐变

    JavaScript如何使用插值实现图像渐变

    这篇文章主要介绍了JavaScript如何使用插值实现图像渐变,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06

最新评论