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

时间:2011-07-14 06:28:33

标签: javascript

我需要一个功能:

function isSame(a, b){
} 

其中,如果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

5 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:4)

在Crockford的网站上有一些改编自计划的例子。具体来说,请查看:

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

这一切都可以在这里找到:

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

这是一个有效的例子:

http://jsfiddle.net/FhGpd/

更新

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

答案 2 :(得分:4)

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

答案 3 :(得分:0)

这是可行的:

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

由于它将函数转换为字符串以比较它们,因此检查空格是否会破坏事物:

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

您可以查看http://jsfiddle.net/webholik/dwaLN/4/自行试用。

答案 4 :(得分:0)

如果有人在阅读此答案时使用Angular.js,您可以使用angular.equals(obj1,obj2);

根据docs

  

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

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

仅通过标识(===)来比较范围和DOMWindow对象。