diff --git a/src/core/Base.js b/src/core/Base.js
index ad73be80..24f59930 100644
--- a/src/core/Base.js
+++ b/src/core/Base.js
@@ -118,12 +118,6 @@ Base.inject(/** @lends Base# */{
          * arrays and properties of objects.
          */
         equals: function(obj1, obj2) {
-            function checkKeys(o1, o2) {
-                for (var i in o1)
-                    if (o1.hasOwnProperty(i) && !o2.hasOwnProperty(i))
-                        return false;
-                return true;
-            }
             if (obj1 === obj2)
                 return true;
             // Call #equals() on both obj1 and obj2
@@ -131,28 +125,33 @@ Base.inject(/** @lends Base# */{
                 return obj1.equals(obj2);
             if (obj2 && obj2.equals)
                 return obj2.equals(obj1);
-            // Compare arrays
-            if (Array.isArray(obj1) && Array.isArray(obj2)) {
-                if (obj1.length !== obj2.length)
-                    return false;
-                for (var i = 0, l = obj1.length; i < l; i++) {
-                    if (!Base.equals(obj1[i], obj2[i]))
-                        return false;
-                }
-                return true;
-            }
+
+            // Deep compare objects or arraays
             // Compare objects
-            if (obj1 && typeof obj1 === 'object'
-                    && obj2 && typeof obj2 === 'object') {
-                if (!checkKeys(obj1, obj2) || !checkKeys(obj2, obj1))
-                    return false;
-                for (var i in obj1) {
-                    if (obj1.hasOwnProperty(i)
-                            && !Base.equals(obj1[i], obj2[i]))
-                        return false;
+            if (obj1 && obj2 &&
+                    typeof obj1 === 'object' &&
+                    typeof obj2 === 'object') {
+                // Compare arrays
+                if (Array.isArray(obj1) && Array.isArray(obj2)) {
+                    if (obj1.length !== obj2.length) return false;
+                    for (var i = 0, l = obj1.length; i < l; i++) {
+                        if (!Base.equals(obj1[i], obj2[i])) return false;
+                    }
+                } else {
+                    // Deep compare objects.
+                    var keys = Object.keys(obj1), key;
+                    var length = keys.length;
+                    // Ensure that both objects contain the same number of properties before comparing deep equality.
+                    if (Object.keys(obj2).length !== length) return false;
+                    while (length--) {
+                        // Deep compare each member
+                        key = keys[length];
+                        if (!(obj2.hasOwnProperty(key) && Base.equals(obj1[key], obj2[key]))) return false;
+                    }
                 }
                 return true;
             }
+
             return false;
         },