Underscore.js: equal
Test for the equality of two variables
by nemesarial
HTML
<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
JavaScript
_.mixin({
/**
Tests for the equality of two variables
valA: first variable
valB: second variable
stringifyStatics: cast non-objects to string so that "1"===1
**/
equal:function(valA,valB,stringifyStatics){
stringifyStatics=!!stringifyStatics;
//check for same type
if(typeof(valA)!==typeof(valB)){
if((_.isObject(valA) || _.isObject(valB))){
return false;
}
}
//test non-objects for equality
if(!_.isObject(valA)){
if(stringifyStatics){
var valAs=''+valA;
var valBs=''+valB;
ret=(''+valA)===(''+valB);
}else{
ret=valA===valB;
}
return ret;
}
//test for length
if(_.size(valA)!=_.size(valB)){
return false;
}
//test for arrays first
var isArr=_.isArray(valA);
//test whether both are array or both object
if(isArr!==_.isArray(valB)){
return false;
}
var ret=true;
if(isArr){
//do test for arrays
_.each(valA,function(val,idx,lst){
if(!ret){return;}
ret=ret && _.equal(val,valB[idx],stringifyStatics);
});
}else{
//do test for objects
_.each(valA,function(val,idx,lst){
if(!ret){return;}
//test for object member exists
if(!_.has(valB,idx)){
ret=false;
// console.log('false: object member mismatch');
return;
}
// test for member equality
ret=ret && _.equal(val,valB[idx],stringifyStatics);
});
}
return ret;
}
});
var result=[];
result.push("stringifyStatics off: " + _.equal(
['a',{b:'b'},[1,2,3]],
['a',{b:'b'},["1",'2',3]]
,false));
result.push("stringifyStatics on: " + _.equal(
['a',{b:'b'},[1,2,3]],
['a',{b:'b'},["1",'2',3]]
,true));
result.push('stringifyStatics and deep nesting: ' + _.equal(
['a',{b:'b',c:[{'someId':1},2]},[1,2,3]],
...