Improve performance of javascript object equality test.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/commit/c137b1ab Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/tree/c137b1ab Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-ui/diff/c137b1ab Branch: refs/heads/0.4.0 Commit: c137b1ab5dc8db0e5643b37b97be5be54bae8e1d Parents: eff8f02 Author: sjcorbett <[email protected]> Authored: Sat Mar 31 16:21:19 2012 +0100 Committer: sjcorbett <[email protected]> Committed: Mon Apr 2 10:29:01 2012 +0100 ---------------------------------------------------------------------- .../web-app/js/console/util/brooklyn-util.js | 48 ++++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-ui/blob/c137b1ab/usage/web-console/web-app/js/console/util/brooklyn-util.js ---------------------------------------------------------------------- diff --git a/usage/web-console/web-app/js/console/util/brooklyn-util.js b/usage/web-console/web-app/js/console/util/brooklyn-util.js index b9d988a..d1dceec 100644 --- a/usage/web-console/web-app/js/console/util/brooklyn-util.js +++ b/usage/web-console/web-app/js/console/util/brooklyn-util.js @@ -14,21 +14,41 @@ Brooklyn.util = (function(){ return (typeof a == typeof b) } - function testEquivalent(a, b) { - var result = true; - if (!typeTest(a, b)) return false; - if (typeof a == 'object') { - for (var p in a) { - result = testEquivalent(a[p], b[p]); - if (!result) return false; - } - for (var p in b) { - result = testEquivalent(b[p], a[p]); - if (!result) return false; - } - return result; + // Object equality test based on code in StackOverflow answer by Jean Vincent + // http://stackoverflow.com/a/6713782/41195 + function testEquivalent(x, y) { + // if both x and y are null or undefined and exactly the same + if ( x === y ) return true; + + // if they are not strictly equal, they both need to be Objects + if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) return false; + + // they must have the exact same prototype chain, the closest we can do is + // test there constructor. + if ( x.constructor !== y.constructor ) return false; + + for ( var p in x ) { + // other properties were tested using x.constructor === y.constructor + if ( ! x.hasOwnProperty( p ) ) continue; + + // allows to compare x[ p ] and y[ p ] when set to undefined + if ( ! y.hasOwnProperty( p ) ) return false; + + // if they have the same strict value or identity then they are equal + if ( x[ p ] === y[ p ] ) continue; + + // Numbers, Strings, Functions, Booleans must be strictly equal + if ( typeof( x[ p ] ) !== "object" ) return false; + + // Objects and Arrays must be tested recursively + if ( ! testEquivalent2( x[ p ], y[ p ] ) ) return false; + } + + for ( p in y ) { + // allows x[ p ] to be set to undefined + if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) return false; } - return (a == b); + return true; } /* DATATABLES UTIL*/
