Check for custom isEqual methods in _.isEqual before other comparisons and add cross-browser support for arguments objects.

Former-commit-id: 56e40f670309aeb0dcda7868c8aa84b5909db1f1
This commit is contained in:
John-David Dalton
2012-07-24 01:45:34 -07:00
parent 7088ab89f1
commit ed89a3e0f8
2 changed files with 24 additions and 10 deletions

View File

@@ -2913,29 +2913,29 @@
function isEqual(a, b, stack) {
stack || (stack = []);
// exit early for identical values
if (a === b) {
// treat `+0` vs. `-0` as not equal
return a !== 0 || (1 / a == 1 / b);
}
// a strict comparison is necessary because `null == undefined`
if (a == null || b == null) {
return a === b;
}
// unwrap any wrapped objects
// unwrap any LoDash wrapped values
if (a._chain) {
a = a._wrapped;
}
if (b._chain) {
b = b._wrapped;
}
// invoke a custom `isEqual` method if one is provided
// use custom `isEqual` method if available
if (a.isEqual && toString.call(a.isEqual) == funcClass) {
return a.isEqual(b);
}
if (b.isEqual && toString.call(b.isEqual) == funcClass) {
return b.isEqual(a);
}
// exit early for identical values
if (a === b) {
// treat `+0` vs. `-0` as not equal
return a !== 0 || (1 / a == 1 / b);
}
// compare [[Class]] names
var className = toString.call(a);
if (className != toString.call(b)) {
@@ -2979,12 +2979,12 @@
result = true,
size = 0;
// add the first collection to the stack of traversed objects
// add `a` to the stack of traversed objects
stack.push(a);
// recursively compare objects and arrays (susceptible to call stack limits)
if (className == arrayClass) {
// compare array lengths to determine if a deep comparison is necessary
if (arrayLikeClasses[className] || (noArgsClass && isArguments(value))) {
// compare lengths to determine if a deep comparison is necessary
size = a.length;
result = size == b.length;

View File

@@ -671,6 +671,20 @@
QUnit.module('lodash.isEqual');
(function() {
test('should work with `arguments` objects (test in IE < 9)', function() {
var args1 = (function() { return arguments; }(1, 2, 3)),
args2 = (function() { return arguments; }(1, 2, 3)),
args3 = (function() { return arguments; }(1, 2));
equal(_.isEqual(args1, args2), true);
equal(_.isEqual(args1, args3), false);
});
test('should respect custom `isEqual` result despite objects strict equaling each other', function() {
var object = { 'isEqual': function() { return false; } };
equal(_.isEqual(object, object), false);
});
test('fixes the JScript [[DontEnum]] bug (test in IE < 9)', function() {
equal(_.isEqual(shadowed, {}), false);
});