From ed89a3e0f8524754f1f9c8650bda2c9200233f1b Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 24 Jul 2012 01:45:34 -0700 Subject: [PATCH] Check for custom `isEqual` methods in `_.isEqual` before other comparisons and add cross-browser support for `arguments` objects. Former-commit-id: 56e40f670309aeb0dcda7868c8aa84b5909db1f1 --- lodash.js | 20 ++++++++++---------- test/test.js | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lodash.js b/lodash.js index 9f05ed000..28cedea08 100644 --- a/lodash.js +++ b/lodash.js @@ -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; diff --git a/test/test.js b/test/test.js index 0d8d6b6d0..fc40c42dd 100644 --- a/test/test.js +++ b/test/test.js @@ -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); });