判断两个对象是否相等需要考虑到以下几点
- -0 和 +0 的相等
- NaN 和 NaN 的相等
- 字符串 和 new String(字符串) 的相等
- 构造函数的问题
- 循环引用的问题
var eq = function(a, b, aStack, bStack) {
if (a === b) return a !== 0 || 1 / a === 1 / b;
if (a == null || b == null) return a === b;
var className = toString.call(a);
if (className !== toString.call(b)) return fasle;
switch(className) {
case '[object RegExp]':
case '[object String]':
return '' + a === '' + b;
case '[object Number]':
if (+a !== +a) return +b !== +b;
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
return +a === +b
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !((typeof aCtor === 'function') && aCtor instanceof aCtor && (typeof bCtor === 'function') && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) {
return false
}
}
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while(length--) {
if (aStack[length] === a) return bStack[length] === b
}
aStack.push(a);
bStack.push(b);
if (areArrays) {
length = a.length;
if (length !== b.length) return false
while(length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false
}
} else {
var keys = _.keys(a), key;
length = keys.length;
if (_.keys(b).length !== length) return false;
while(length--) {
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
aStack.pop();
bStack.pop();
return true;
}
_.isEqual = function(a,b) {
return eq(a, b)
}