如何用 JavaScript 测试两个对象是否相同?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6689250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:32:24  来源:igfitidea点击:

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

javascript

提问by wong2

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, but I found that [] === []will return false.
Some results that I expect this function can gave:

其中,如果a和b相同,则返回true。
,我试过了return a === b,但我发现[] === []会返回false。
我希望这个函数可以给出一些结果:

isSame(3.14, 3.14);  // true  
isSame("hello", "hello"); // true  
isSame([], []); // true  
isSame([1, 2], [1, 2]); // true  
isSame({ a : 1, b : 2}, {a : 1, b : 2}); //true  
isSame([1, {a:1}], [1, {a:1}]);  //true

采纳答案by Adam

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

在 Crockford 的网站上有一些改编自方案的例子。具体请看:

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

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

Here is a working example:

这是一个工作示例:

http://jsfiddle.net/FhGpd/

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.

刚刚根据OP编写了一些测试用例。原来我需要修改 sub1 函数来检查 <= 0 not === 0 否则 isEqual(3.14, 3.14) 炸了堆栈。此外, isEqual 不适用于对象比较,因此您需要自行处理。但是,如果您遵循 Crockford 站点上的示例,您将看到编写可用于检查对象相等性的递归方法是多么容易和有趣。

回答by ThiefMaster

You could embed Underscore.jsand 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.

您可以嵌入Underscore.js并使用_.isEqual(obj1, obj2). 该函数适用于任意对象,并使用最有效的方法来测试给定对象的相等性。

回答by TheBrain

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

最好的方法是使用 JSON 序列化程序。将两者序列化为字符串并比较字符串。

回答by Ankit

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.

您可以查看http://jsfiddle.net/webholik/dwaLN/4/自己尝试一下。

回答by Jayant Bhawal

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

如果有人阅读这个答案正在使用Angular.js,你可以使用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 NaNas 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 (===).

确定两个对象或两个值是否等效。支持值类型、正则表达式、数组和对象。如果以下至少一项为真,则两个对象或值被认为是等效的:

  • 对象或值都通过===比较。
  • 两个对象或值都属于同一类型,并且通过将它们与 进行比较,它们的所有属性都相等angular.equals
  • 两个值都是NaN。(在 JavaScript 中,NaN == NaN => false. 但我们认为两个NaN是相等的)。
  • 两个值都表示相同的正则表达式(在 JavaScript 中,/abc/ == /abc/ => false. 但是当它们的文本表示匹配时,我们认为两个正则表达式相等)。
  • 在属性比较期间,函数类型的属性和名称以 开头的属性$将被忽略。

Scope 和 DOMWindow 对象仅通过 identify 进行比较(===)