diff --git a/objectDiff.js b/objectDiff.js index 36359b1..9f1addf 100644 --- a/objectDiff.js +++ b/objectDiff.js @@ -5,7 +5,7 @@ var objectDiff = typeof exports != 'undefined' ? exports : {}; * @param {Object} b * @return {Object} */ -objectDiff.diff = function diff(a, b) { +objectDiff.diff = function diff(a, b, ignore) { if (a === b) { return { @@ -13,11 +13,20 @@ objectDiff.diff = function diff(a, b) { value: a } } + if (a.__diffComparedTo__ === b && b.__diffComparedTo__ === a) { + return true; + } var value = {}; var equal = true; + var ignoredKeys = ['__diffComparedTo__'].concat(ignore || []); + + a.__diffComparedTo__ = b; + b.__diffComparedTo__ = a; for (var key in a) { + if (ignoredKeys.indexOf(key) != -1) { continue; } + if (key in b) { if (a[key] === b[key]) { value[key] = { @@ -28,7 +37,7 @@ objectDiff.diff = function diff(a, b) { var typeA = typeof a[key]; var typeB = typeof b[key]; if (a[key] && b[key] && (typeA == 'object' || typeA == 'function') && (typeB == 'object' || typeB == 'function')) { - var valueDiff = diff(a[key], b[key]); + var valueDiff = diff(a[key], b[key], ignore); if (valueDiff.changed == 'equal') { value[key] = { changed: 'equal', @@ -57,6 +66,8 @@ objectDiff.diff = function diff(a, b) { } for (key in b) { + if (ignoredKeys.indexOf(key) != -1) { continue; } + if (!(key in a)) { equal = false; value[key] = { @@ -66,6 +77,9 @@ objectDiff.diff = function diff(a, b) { } } + delete a.__diffComparedTo__; + delete b.__diffComparedTo__; + if (equal) { return { changed: 'equal', @@ -85,7 +99,7 @@ objectDiff.diff = function diff(a, b) { * @param {Object} b * @return {Object} */ -objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { +objectDiff.diffOwnProperties = function diffOwnProperties(a, b, ignore) { if (a === b) { return { @@ -93,13 +107,25 @@ objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { value: a } } + if (a && b && a.__diffComparedTo__ === b && b.__diffComparedTo__ === a) { + return true; + } var diff = {}; var equal = true; - var keys = Object.keys(a); + var typeofA = typeof a; + var typeofB = typeof b; + var keys = []; + var ignoredKeys = ['__diffComparedTo__'].concat(ignore || []); + + if (a && typeofA === 'object') { keys = Object.keys(a); } + if (a) { a.__diffComparedTo__ = b; } + if (b) { b.__diffComparedTo__ = a; } for (var i = 0, length = keys.length; i < length; i++) { var key = keys[i]; + if (ignoredKeys.indexOf(key) != -1) { continue; } + if (b.hasOwnProperty(key)) { if (a[key] === b[key]) { diff[key] = { @@ -110,7 +136,7 @@ objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { var typeA = typeof a[key]; var typeB = typeof b[key]; if (a[key] && b[key] && (typeA == 'object' || typeA == 'function') && (typeB == 'object' || typeB == 'function')) { - var valueDiff = diffOwnProperties(a[key], b[key]); + var valueDiff = diffOwnProperties(a[key], b[key], ignore); if (valueDiff.changed == 'equal') { diff[key] = { changed: 'equal', @@ -138,10 +164,13 @@ objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { } } - keys = Object.keys(b); + keys = []; + if (b && typeofB === 'object') { keys = Object.keys(b); } for (i = 0, length = keys.length; i < length; i++) { key = keys[i]; + if (ignoredKeys.indexOf(key) != -1) { continue; } + if (!a.hasOwnProperty(key)) { equal = false; diff[key] = { @@ -151,11 +180,20 @@ objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { } } - if (equal) { + if (a) { delete a.__diffComparedTo__; } + if (b) { delete b.__diffComparedTo__; } + + if (equal && (typeofA === typeofB) && (typeofA === 'object')) { return { value: a, changed: 'equal' } + } else if (equal) { + return { + changed: 'primitive change', + removed: a, + added: b + } } else { return { changed: 'object change', @@ -177,6 +215,14 @@ objectDiff.diffOwnProperties = function diffOwnProperties(a, b) { var diff = changes.value; if (changes.changed == 'equal') { return inspect(diff); + } else if (changes.changed == 'primitive change') { + return [ + '