Mapping the differences between JavaScript objects The reason I want to do this is that the JavaScript objects are created from XML elements and if the element has changed I want to be able to detect that change in the JavaScript objects. So I wrote a function which maps out the differences between the first and second object. Can you improve on this function? (mapObjectDifferences, not the helper functions.)

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;MAP OBJECT DIFFERENCES&lt;/title&gt;
&lt;script type="text/javascript"&gt;

    function isArray(object) {
        return Object.prototype.toString.apply(object) == "[object Array]";
    }

    function getType(variable) {
        var type = typeof variable;
        if (type == "object")
            if (isArray(variable))
                return "array";
        return type;
    }

    function arrayToObject(array) {
        var object = {};
        for (var i = 0; i &lt; array.length; ++i)
            if (array[i] !== "undefined") object[i] = array[i];
        return object;
    }

    function mapObjectDifferences(outerObject, innerObject) {
        var _mapObjectDifferences = function (outerObject, innerObject, parentMap, parentName) {
            var localMap = {};
            for (var outerProp in outerObject) {
                if (outerObject.hasOwnProperty(outerProp)) {
                    var match = false;
                    var outerPropValue = outerObject[outerProp];
                    var outerType = getType(outerPropValue);
                    var result;
                    for (var innerProp in innerObject) {
                        if (innerObject.hasOwnProperty(innerProp)) {
                            var innerPropValue = innerObject[innerProp];
                            var innerType = getType(innerPropValue);
                            if (outerProp == innerProp &amp;&amp; outerType == innerType) {
                                match = true;
                                if (outerType == "array" || outerType == "object") {
                                    if (outerType == "array") {
                                        outerPropValue = arrayToObject(outerPropValue);
                                        innerPropValue = arrayToObject(innerPropValue);
                                    }
                                    _mapObjectDifferences(outerPropValue, innerPropValue, localMap, outerProp);
                                }
                                break;
                            }
                        }
                    }
                    if (match == false) {
                        localMap[outerProp] = outerType;
                        if (parentMap)
                            parentMap[parentName] = localMap;
                    }
                    else if (parentMap) {
                        var difChild = false;
                        for (var prop in localMap)
                            if (localMap.hasOwnProperty(prop)) {
                                difChild = true;
                                break;
                            }
                        if (difChild == true)
                            parentMap[parentName] = localMap;
                    }
                }
            }
            return localMap;
        }
        return _mapObjectDifferences(outerObject, innerObject);
    }

    var o1 = {
        val: "level one",
        val2: 1,
        val3: 3,
        m: {
            s2: "this is level two",
            l1: ["a", "b", "c", 1, {a:"a"}],
            ao: [{ x: "1" }, { y: 1 }, { z: 1}]
        },
        n: {
            n1: { abc: 123 }
        }
    };
    var o2 = {
        val: "level on23e",
        val2: 1,

        m: {
            s3: "this is level two",
             l1: ["a", "b", "c"],
            ao: [{ x: 1 }, { y: 1 }, { z: "3"}]
        },
        n: {
            n1: { abc: "abc" }
        }
    }
    var result = mapObjectDifferences(o1, o2);
    debugger;
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
The existing suggestions are good for trimming down your current code, but, as always, the most important thing to optimize is the algorithm itself. I took a crack at your problem, as I understand it, and here's the result:

function difference(o1, o2) {
    var k, kDiff,
        diff = {};
    for (k in o1) {
        if (!o1.hasOwnProperty(k)) {
        } else if (typeof o1[k] != 'object' || typeof o2[k] != 'object') {
            if (!(k in o2) || o1[k] !== o2[k]) {
                diff[k] = o2[k];
            }
        } else if (kDiff = difference(o1[k], o2[k])) {
            diff[k] = kDiff;
        }
    }
    for (k in o2) {
        if (o2.hasOwnProperty(k) &amp;&amp; !(k in o1)) {
            diff[k] = o2[k];
        }
    }
    for (k in diff) {
        if (diff.hasOwnProperty(k)) {
            return diff;
        }
    }
    return false;
}


Note that I didn't try to mimic your code exactly:


Arrays are compared thoroughly, not just on numbered properties.
Difference map contains new values themselves, not their types.
If there are no differences then the function returns false, not {}.