Показать сообщение отдельно
  #24 (permalink)  
Старый 11.10.2012, 04:29
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,587

Примерно так(хотя мои представления о сравнении немого отличаются от оных предыдущего постера) :
(function(a){ //расширение алерта, для вывода нескольких значений(мне так нравится=))
	window.alert = function(){
		a(Array.prototype.slice.call(arguments).join('\n'))
	}
}(window.alert))
 
 
if (!Object.keys) { //Object.keys для ослов(с MDN)
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length
 
    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object')
 
      var result = []
 
      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop)
      }
 
      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i])
        }
      }
      return result
    }
  })()
};



 
Object.equals = function( first, second ){
	
	var cache = []; //кеш обьектов, для избежания рекурсии
	
	function inCache( first, second ){
		var i = cache.length;
		while(i--) if( 
			( cache[i][0] === first || cache[i][0] === second) && (cache[i][1] === second  || cache[i][1] === first ) 
		) return true;
		return false
	}
	
	return function eq(f, s){
		if ( f === s ) return true; //сравниваем обычным образом
		if ( f instanceof Date && s instanceof Date ) return +f === +s; //время
		if ( typeof f !== 'object' || typeof s !== 'object' ) return false; //если хотябы один из аргументов не объект (положительный случай для необъектов рассмотрен выше)
		if( inCache(f, s) ) return true; //есть в кеше
		cache.push( [f , s] ); //кешируем
		
		var keys = Object.keys(f), i = keys.length; //получаем ключи
		if (Object.keys(s).length !== i ) return false; //если количество ключей не совпадает
		while(i--) if( !eq(f[keys[i]], s[keys[i]]) ) return false; //рекурсивный вызов
		
		return true
	}(first, second)
}

alert(
	'Обычные объекты:',
	Object.equals({a:[1,2,3],b:2}, {b:2,a:[1,2,3]}), //true
	Object.equals(null, null), //true
	Object.equals(1, 1), //true
	Object.equals(1, '1'), //false
	Object.equals(1, {a:1}), //false
	Object.equals([1,2], [1,2]), //true
	Object.equals(new Date(), new Date()) //true
)

a = {x:1,c:{r:0}};
b = {x:1,c:{r:0}};
c = {x:1,c:{r:0}};
a.c.r = a;
b.c.r = b;
c.c.r = c;
a.z = b;
b.z = c;
c.z = a;
alert( 
	'Рекурсивные:',
	Object.equals(a, b), //true
	Object.equals(a, c), //true
	Object.equals(c, b), //true
	Object.equals(a, {x:1,c:{r:''}}) //false
)
__________________
29375, 35

Последний раз редактировалось Aetae, 11.10.2012 в 04:34.
Ответить с цитированием