我需要一个功能:
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
答案 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
这是一个有效的例子:
刚刚根据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对象。