Compare two JavaScript objects and return another object with the difference

In the following example, we'll compare two objects in JavaScript and return the difference.

First object

javascript
const Bar = {

    'category': 'football',
    'city': 'Barcelona',
    'trophies': {
        'championsLeague': 5,
        'copa': 30
    },
    'sponsors': ['Nike', 'Rakuten', 'Beko', 'CaixaBank']

}

Second object

javascript
const Mad = {

    'category': 'football',
    'city': 'Madrid',
    'trophies': {
        'championsLeague': 13,
        'copa': 19
    },
    'sponsors': ['Adidas', 'Emirates', 'Audi', 'CaixaBank']
    
}

Expected result

If we substract the first object from the second (Mad - Bar), we expect:

javascript
const Mad_minus_Bar = {

    'city': 'Madrid',
    'trophies': {
        'championsLeague': 13,
        'copa': 19
    },
    'sponsors': ['Adidas', 'Emirates', 'Audi']

}

Whereas if we substract the first object from the second (Bar - Mad), we expect:

javascript
const Bar_minus_Mad = {

    'city': 'Barcelona',
    'trophies': {
        'championsLeague': 5,
        'copa': 30
    },
    'sponsors': ['Nike', 'Rakuten', 'Beko']

}

Note how coincidences in both objects, like category: 'football' and sponsors[3] = 'CaixaBank' have disappeared from the results.

The function

javascript
const compareObjects = (obj1, obj2) => {

    // Empty object to store the difference between obj1 and obj2
    let diff = {};

    Object.keys(obj2).map(key => {

        // If type of properties are different
        // Create new property in diff object
        if(typeof(obj1[key]) !== typeof(obj2[key])){
            diff[key] = obj2[key];
        }
        // If both properties are arrays
        // Check elements and add them if they are differnt in 'diff' object
        else if(Array.isArray(obj1[key]) && Array.isArray(obj2[key])){
            diff[key] = obj2[key].filter(elem => !obj1[key].includes(elem));                
        }
        // If both properties are objects
        // Call again this function recursively
        else if(typeof(obj1[key]) === 'object' && typeof(obj2[key]) === 'object'){
            diff[key] = compareObjects(obj1[key], obj2[key]);
        }
        // If properties don't match
        // Create new property in diff object
        else if(obj1[key] !== obj2[key]){                                        
            diff[key] = obj2[key];
        }

    });    

    // Deleting empty keys in diff object after comparing obj1 and obj2
    Object.keys(diff).map(key => {
        Object.keys(diff[key]).length === 0 && typeof(diff[key]) === 'object' && delete diff[key];
    });

    return diff;

}

Calling the function:

javascript
let Mad_minus_Bar = compareObjects(Mad, Bar);
let Bar_minus_Mad = compareObjects(Bar, Mad);

Even with less Champions Leagues, I'll still ❤️ Barça.

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.