js中判斷Object、Array、Function等引用類型對象是否相等
更新時(shí)間:2012年08月29日 00:14:10 作者:
項(xiàng)目中有時(shí)會(huì)需要對引用類型進(jìn)行比較,如常見的object和array,我們知道,引用類型無法直接使用 == 或=== 取得期待結(jié)果,因此需要一個(gè)迭代的compare函數(shù)轉(zhuǎn)化成原始類型進(jìn)行比較
在迭代中,我們還要注意的是,對象或者數(shù)組中的元素可能是一個(gè)任意值——除了原始類型值、object、arrray外,這個(gè)值還可能是一個(gè)方法、一個(gè)DOM對象或者window對象,可能你已經(jīng)注意到了,有部分引用類型是不能進(jìn)行迭代的,需要分支判斷,代碼如下:
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'); //硬編碼中聲明函數(shù)的方式會(huì)影響到toString的結(jié)果,因此用正則進(jìn)行格式化
};
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
復(fù)制代碼 代碼如下:
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'); //硬編碼中聲明函數(shù)的方式會(huì)影響到toString的結(jié)果,因此用正則進(jìn)行格式化
};
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類型轉(zhuǎn)換與引用類型詳解(Boolean_Number_String)
- js中的值類型和引用類型小結(jié) 文字說明與實(shí)例
- javascript中基本類型和引用類型的區(qū)別分析
- JavaScript基本數(shù)據(jù)類型及值類型和引用類型
- JavaScript之引用類型介紹
- JavaScript數(shù)據(jù)類型之基本類型和引用類型的值
- JavaScript中值類型與引用類型實(shí)例說明
- 跟我學(xué)習(xí)javascript的基本類型和引用類型
- JavaScript中值類型和引用類型的區(qū)別
- 理解javascript中的嚴(yán)格模式
- 深入理解javascript嚴(yán)格模式(Strict Mode)
- JavaScript 引用類型實(shí)例詳解【數(shù)組、對象、嚴(yán)格模式等】
相關(guān)文章
javascript實(shí)現(xiàn)相同事件名稱,不同命名空間的調(diào)用方法
這篇文章主要介紹了javascript實(shí)現(xiàn)相同事件名稱,不同命名空間的調(diào)用方法,涉及javascript命名空間及事件調(diào)用的技巧,需要的朋友可以參考下2015-06-06
js實(shí)現(xiàn)無感刷新的實(shí)踐(附前后端實(shí)現(xiàn))
無感刷新機(jī)制的目的是在用戶不知情的情況下,自動(dòng)更新其認(rèn)證令牌本文,主要介紹了js實(shí)現(xiàn)無感刷新的實(shí)踐(附前后端實(shí)現(xiàn)),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04
chorme 瀏覽器記住密碼后input黃色背景處理方法(兩種)
使用chrome瀏覽器選擇記住密碼的賬號(hào),輸入框會(huì)自動(dòng)加上黃色的背景,有些設(shè)計(jì)輸入框是透明背景的,需要去除掉這個(gè)黃色的背景。下面給大家分享chorme 瀏覽器記住密碼后input黃色背景處理方法,一起看看吧2017-11-11
layui的布局和表格的渲染以及動(dòng)態(tài)生成表格的方法
今天小編就為大家分享一篇layui的布局和表格的渲染以及動(dòng)態(tài)生成表格的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
Highcharts 非常實(shí)用的Javascript統(tǒng)計(jì)圖demo示例
官網(wǎng)實(shí)例中給出了各式各樣的demo,可以參照document修改自己需要的即可,本文實(shí)現(xiàn)的是一個(gè)學(xué)生成績走勢demo,有需求的朋友可以參考下哈,希望對大家有所幫助2013-07-07
js猜數(shù)字小游戲的簡單實(shí)現(xiàn)代碼
這篇文章介紹了js猜數(shù)字小游戲的簡單實(shí)現(xiàn)代碼,很好玩的游戲哦,可以看看你的智商 是否驚人額2013-07-07
javascript實(shí)現(xiàn)倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)倒計(jì)時(shí)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02
JavaScript如何使用插值實(shí)現(xiàn)圖像漸變
這篇文章主要介紹了JavaScript如何使用插值實(shí)現(xiàn)圖像漸變,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06

