How to test if two objects are the same with JavaScript?

前端 未结 5 2001
慢半拍i
慢半拍i 2021-02-15 17:35

I need a function:

function isSame(a, b){
} 

In which, if a and b are the same, it returns true.
, I tried return a === b, b

相关标签:
5条回答
  • 2021-02-15 17:55

    If anyone reading this answer is using Angular.js, you can use angular.equals(obj1,obj2);

    According to the docs:

    Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and objects. Two objects or values are considered equivalent if at least one of the following is true:

    • Both objects or values pass === comparison.
    • Both objects or values are of the same type and all of their properties are equal by comparing them with angular.equals.
    • Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal).
    • Both values represent the same regular expression (In JavaScript, /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual representation matches).
    • During a property comparison, properties of function type and properties with names that begin with $ are ignored.

    Scope and DOMWindow objects are being compared only by identify (===).

    0 讨论(0)
  • 2021-02-15 18:02

    You could embed Underscore.js and use _.isEqual(obj1, obj2). The function works for arbitrary objects and uses whatever is the most efficient way to test the given objects for equality.

    0 讨论(0)
  • 2021-02-15 18:02

    the best way to do that is to use a JSON serializer. serialize both to string and compare the string.

    0 讨论(0)
  • 2021-02-15 18:09

    Here is something that can work:

    function isSame(obj1, obj2, prefer){
    // Optional parameter prefer allows to only check for object keys and not both keys and values of an object
    var obj_prefer = prefer || "both"; 
    function checkArray(arr1, arr2){
        for(var i = 0, j = obj1.length; i<j; i++){
            if(obj1[i] !== obj2[i]){return false;}
        }
        return true;
    }
    
    function checkValues(obj_1, obj_2){
        for(var prop in obj_1){
            if(typeof obj_1[prop] === "function"){  // converting functions to string so that they can be matched
                obj_1[prop] = String(obj_1[prop]);
                obj_2[prop] = String(obj_2[prop]);
            }
    
            if(obj_1[prop] !== obj_2[prop]){ return false;}
        }
        return true;
    }
    // The built in === will check everything except when typeof object is "object"
    if ( typeof obj1 === "object"){
        // typeof Array is object so this is an alternative
        if((typeof obj1.push === "function") && (!obj1.hasOwnProperty('push'))){
            return checkArray(obj1, obj2);
            }
    
        else{
                if( obj_prefer !== "keys"){   // do not check for values if obj_prefer is "keys"
                    return checkValues(obj1, obj2);
                }
                var keys_1 = Object.keys(obj1);
                var keys_2 = Object.keys(obj2);
                if(!checkArray(keys_1, keys_2)){return false;}
    
                return true;
        }
    }
    
        // I thought undefined === undefined will give false but it isn't so you can remove it    
        if( typeof obj1 === "undefined" && typeof obj2 === "undefined" ){return true}
    
        if(typeof obj1 === "function"){
            return String(obj1) === String(obj2);
        }
    
            return obj1 === obj2;
    }
    console.log(isSame(2, 2));  //true
    console.log(isSame([1], [1])); // true
    

    Since it converts Functions into Strings to compare them, check out for spaces as that can break things:

    var func1 = function(){},
        func2 = function(){ }; // function with extra space
    isSame(func1, func2); // false
    

    You can check out http://jsfiddle.net/webholik/dwaLN/4/ to try it yourself.

    0 讨论(0)
  • 2021-02-15 18:16

    There are some examples, adapted from scheme, on Crockford's site. Specifically, check out:

    function isEqual(s1, s2) {
        return isAtom(s1) && isAtom(s2) ? isEqan(s1, s2) :
                isAtom(s1) || isAtom(s2) ? false :
                isEqlist(s1, s2);
    }
    

    It can all be found here:

    http://javascript.crockford.com/little.js

    Here is a working example:

    http://jsfiddle.net/FhGpd/

    Update:

    Just wrote some test cases based on the OP. Turns out I needed to modify the sub1 function to check <= 0 not === 0 otherwise isEqual(3.14, 3.14) blew the stack. Also, isEqual does not work for object comparison, so you are on your own there. However, if you follow the examples on Crockford's site you will see how easy and fun it is to write recursive methods that could be used to check for object equality.

    0 讨论(0)
提交回复
热议问题