From ea5dea4d614b218cd807e0ae035a186d4eec5898 Mon Sep 17 00:00:00 2001 From: "Anderson, Ben" Date: Thu, 23 Oct 2014 13:59:30 -0400 Subject: [PATCH 1/2] making the equals method work when the obj graph has circular dependencies --- src/Angular.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index 097f2977c036..c766d78f43d2 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -825,18 +825,24 @@ function shallowCopy(src, dst) { * @param {*} o2 Object or value to compare. * @returns {boolean} True if arguments are equal. */ -function equals(o1, o2) { +function equals(o1, o2, visitedObjArr) { if (o1 === o2) return true; if (o1 === null || o2 === null) return false; if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN var t1 = typeof o1, t2 = typeof o2, length, key, keySet; if (t1 == t2) { if (t1 == 'object') { + if (typeof visitedObjArr == 'undefined') { + visitedObjArr = {}; + } else { + if (o1 in visitedObjArr) return true; + } + visitedObjArr[o1] = true; if (isArray(o1)) { if (!isArray(o2)) return false; if ((length = o1.length) == o2.length) { for (key=0; key Date: Fri, 24 Oct 2014 11:20:09 -0400 Subject: [PATCH 2/2] making the equals method work when the obj graph has circular references. This uses WeakMap. --- src/Angular.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Angular.js b/src/Angular.js index c766d78f43d2..7211d85604f2 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -825,24 +825,31 @@ function shallowCopy(src, dst) { * @param {*} o2 Object or value to compare. * @returns {boolean} True if arguments are equal. */ -function equals(o1, o2, visitedObjArr) { +function equals(o1, o2, comparisons) { if (o1 === o2) return true; if (o1 === null || o2 === null) return false; if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN var t1 = typeof o1, t2 = typeof o2, length, key, keySet; if (t1 == t2) { if (t1 == 'object') { - if (typeof visitedObjArr == 'undefined') { - visitedObjArr = {}; + comparisons || (comparisons = new WeakMap()); + if (comparisons.has(o1) && comparisons.get(o1).has(o2)) { + return true; } else { - if (o1 in visitedObjArr) return true; + if (!comparisons.has(o1)) { + comparisons.set(o1, new WeakMap()); + } + comparisons.get(o1).set(o2, true); + if (!comparisons.has(o2)) { + comparisons.set(o2, new WeakMap()); + } + comparisons.get(o2).set(o1, true); } - visitedObjArr[o1] = true; if (isArray(o1)) { if (!isArray(o2)) return false; if ((length = o1.length) == o2.length) { for (key=0; key