Whether the two objects are equal or not

let a= {
    id:1,
    hobby:[1,3]
}

let b= {
    id:1,
    hobby:[1,2,3]
}

how does js judge whether an and b are equal? the value in objects may be strings, array objects, etc.

Dec.09,2021

first of all, JSON.stringify is impossible, and secondly, this classical problem can be found everywhere. object-comparison-in-javascript

 x = {a: 1, b: 2};
 y = {b: 2, a: 1};
 JSON.stringify(x)===JSON.stringify(y); //false

A common way to compare equality is to loop object properties, but it's slow. The limitation of JSON.stringify is so high that it is not allowed if the order of attributes is different.


how to judge the equality of two objects
the article explains in great detail, directly using his final eq function to achieve comparison.

the following code is the final eq function code in the original text:

    return toString.call(obj) === '[object Function]' }

function eq(a, b, aStack, bStack) {

    // ===  true  +0  -0
    if (a === b) return a !== 0 || 1 / a === 1 / b;

    // typeof null  object  null 
    if (a == null || b == null) return false;

    //  NaN
    if (a !== a) return b !== b;

    //  a  false
    var type = typeof a;
    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;

    //  deepEq 
    return deepEq(a, b, aStack, bStack); };

function deepEq(a, b, aStack, bStack) {

    // a  b  [[class]]   true
    var className = toString.call(a);
    if (className !== toString.call(b)) return false;

    switch (className) {
        case '[object RegExp]':
        case '[object String]':
            return '' + a === '' + b;
        case '[object Number]':
            if (+a !== +a) return +b !== +b;
            return +a === 0 ? 1 / +a === 1 / b : +a === +b;
        case '[object Date]':
        case '[object Boolean]':
            return +a === +b;
    }

    var areArrays = className === '[object Array]';
    // 
    if (!areArrays) {
        // 
        if (typeof a != 'object' || typeof b != 'object') return false;

        var aCtor = a.constructor,
            bCtor = b.constructor;
        // aCtor  bCtor  Object aCtor  bCtor 
        if (aCtor !== bCtor && !(isFunction(aCtor) && aCtor instanceof aCtor && isFunction(bCtor) && bCtor instanceof bCtor) &&
('constructor' in a && 'constructor' in b)) {
            return false;
        }
    }


    aStack = aStack || [];
    bStack = bStack || [];
    var length = aStack.length;

    // 
    while (length--) {
        if (aStack[length] === a) {
            return bStack[length] === b;
        }
    }

    aStack.push(a);
    bStack.push(b);

    // 
    if (areArrays) {

        length = a.length;
        if (length !== b.length) return false;

        while (length--) {
            if (!eq(a[length], b[length], aStack, bStack)) return false;
        }
    }
    // 
    else {

        var keys = Object.keys(a),
            key;
        length = keys.length;

        if (Object.keys(b).length !== length) return false;
        while (length--) {

            key = keys[length];
            if (!(b.hasOwnProperty(key) && eq(a[key], b[key], aStack, bStack))) return false;
        }
    }

    aStack.pop();
    bStack.pop();
    return true;

}

use:

let a= {
    id:1,
    hobby:[1,3]
}

let b= {
    id:1,
    hobby:[1,2,3]
}
let c= {
    hobby:[1,3],
    id:1,
}
let d= {
    hobby:[1,2,3],
    id:1,
}

eq(a,b) //false
eq(a,c) //true
eq(a,d) //false
eq(b,c) //false
eq(b,d) //true
eq(c,d) //false

after reading several answers from others, I feel that this method in this article is really powerful.
also learned by the way.
^ _ ^


take a look at shallowEqual


used by Facebook.
let a= {
    id:1,
    hobby:[1,2,3]
}

let b = {
    hobby:[1,2,3],
    id:1,
}
function keySort(target){
    const newObj = {}
    Object.keys(target).sort().map(key => newObj[key] = target[key])
    return newObj
}
console.log(JSON.stringify(keySort(a)) === JSON.stringify(keySort(b)))  // true

Why do you spray JSON.stringify,? it doesn't support sorting. Can't you line it up and take it out? (manual dog head)


Is

deep or shallow?

use JSON.stringify directly if you are deep

use Object.keys for shallow words

Menu