Немного доработал предыдущий вариант, если кому интересно.
/** сравнить объекты по значению рекурсивно все свойства.
*@param Object firstObj один из объектов для сравнения
*@param Object secondObject другой объект для сравнения
*@return boolean true одинаковы, false - различаются
*Пр.: Object.equals({a:[1,2,3],b:2}, {b:2,a:[1,2,3]}); //true
* Object.equals(null, null); //false
* Object.equals(1, 1); //true
* Object.equals(1, '1');//true
* Object.equals(1, {a:1});//false
* Object.equals([1,2], [1,2]);//true
* Object.equals(new Date(), new Date())//true
*
* var d= new Date();
* var d2= new Date(d.getTime()+3600000);
* Object.equals(d, d2); //false
* Object.equals(d, d); //true
* Object.equals(d, new Date(d.getTime())); //true
**/
Object.equals = function( firstObj, secondObject ){
if ((null==firstObj)||(null==secondObject)) return false; //null сравниваем правильно. Если хоть в одном операнде значит false
if (('object'!=typeof firstObj) && ('object'!=typeof secondObject)) return firstObj==secondObject;//оба из простых - сравнение простых значений.
else if (('object'!=typeof firstObj) || ('object'!=typeof secondObject)) return false;//сравнивается простое значение с объектом - всегда не равны
//в этой точке только если сравниваем именно объекты (оба)
//отдельно для дат
if ((firstObj instanceof Date) && (secondObject instanceof Date)) return firstObj.getTime()==secondObject.getTime(); //исключение для дат. сравним их по микросекундам
else if ((firstObj instanceof Date) && (secondObject instanceof Date)) return false;//Если дата сравнивается с чем-то ещё -то всегда выдать несоответствие
//далее сравниваем нормальные объекты
var keysFirstObj = Object.keys( firstObj );
var keysSecondObject = Object.keys( secondObject );
if ( keysFirstObj.length != keysSecondObject.length ) {return false;}
return !keysFirstObj.filter(function( key ){
if ( typeof firstObj[key] == "object" || Array.isArray( firstObj[key] ) ) {
return !Object.equals(firstObj[key], secondObject[key]);
} else {
return firstObj[key] !== secondObject[key];
}
}).length;
}
alert(Object.equals({a:[1,2,3],b:2}, {b:2,a:[1,2,3]})); //true
alert(Object.equals(null, null); //false
alert(Object.equals(1, 1); //true
alert(Object.equals(1, '1');//true
alert(Object.equals(1, {a:1});//false
alert(Object.equals([1,2], [1,2]);//true
alert(Object.equals(new Date(), new Date())//true