jQuery对象的相等性

163

如何判断两个jQuery对象是否相等?我想要在一个数组中查找特定的jQuery对象。

$.inArray(jqobj, my_array);//-1    
alert($("#deviceTypeRoot") == $("#deviceTypeRoot"));//False
alert($("#deviceTypeRoot") === $("#deviceTypeRoot"));//False
7个回答

246

自从jQuery 1.6版以后,你可以使用.is方法。下面是一年前的回答...

var a = $('#foo');
var b = a;


if (a.is(b)) {
    // the same object!
}

如果您想查看两个变量是否实际上是同一个对象,例如:

var a = $('#foo');
var b = a;

如果您需要检查它们的唯一ID,则可以检查它们的唯一ID。每次创建新的jQuery对象时,它都会获得一个ID。

if ($.data(a) == $.data(b)) {
    // the same object!
}

虽然简单的 a === b 也可以达到相同的效果,但是上述做法可以让下一个开发者清楚地知道你正在测试什么。

无论如何,这可能不是你想要的。如果你想要检查两个不同的 jQuery 对象是否包含相同的元素集合,那么你可以使用以下代码:

$.fn.equals = function(compareTo) {
  if (!compareTo || this.length != compareTo.length) {
    return false;
  }
  for (var i = 0; i < this.length; ++i) {
    if (this[i] !== compareTo[i]) {
      return false;
    }
  }
  return true;
};

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}

1
当只有一个元素时,此解决方案简化为thephpdeveloper所提供的解决方案。另一种将jQuery对象视为相等的方法是它们是否具有相同的选择器和上下文。这很容易测试:A.selector === B.selector && A.context === B.context。通常上下文将始终相同,因此我们只需考虑选择器。 - Casebash
2
@Casebash - 是的,但请考虑到几个选择器最终可能会得到相同的结果集,例如:$(':first') 和 $('*:first')。 - nickf
3
请注意 @rampion 和 nickf,jQuery 的 is() 方法不会检查选择器是否完全相同,仅仅是检查它们是否有重叠。请看这个例子:http://jsfiddle.net/bnhkm/1/ - Bob Stein
你的 equals 函数似乎是有顺序敏感性的。像 https://dev59.com/l10b5IYBdhLWcg3wENmK#29648479 这样的函数可以在更多情况下工作,尽管它速度较慢。 - Jayen
equals函数只适用于对象只有一层的情况!比较a=b = [{dir: 'test', sort: [{test: {test:1} }] }]是无效的。 - DavidDunham
1
问题是关于 jQuery 对象,而不是一般的对象。 - nickf

17

如果你还不知道,你可以通过以下方式获得原始对象:

alert($("#deviceTypeRoot")[0] == $("#deviceTypeRoot")[0]); //True
alert($("#deviceTypeRoot")[0] === $("#deviceTypeRoot")[0]);//True

因为 $("#deviceTypeRoot") 也返回了选择器所选中的对象数组。


1
这两个警告框将显示 true,因为您正在比较DOM元素的引用,=====将给出相同的结果(不需要类型强制转换,它们只是两个对象引用)。 - Christian C. Salvadó
你的第二条语句实际上返回了True。 - Casebash
啊,是的,这是真的。复制粘贴错误 =D - mauris

15
"$.fn.equals(...) 解决方案可能是最干净和最优雅的解决方案。"
"我尝试过一些快速而粗略的方法,比如这样:"
JSON.stringify(a) == JSON.stringify(b)

它可能很昂贵,但舒适的事情是它是隐式递归的,而优雅的解决方案则不是。
这只是我的个人意见。

1
这对于检查两个jQuery对象的相等性并不好用,但适用于标准对象,例如 "{a:'x',b:'y',c:'z'} == {a:'x',b:'y',c:'z'}"。我想知道为什么没有jQuery.isEqual(a, b)... - iRaS
16
这是错误的,对象属性的顺序很重要。因此,如果你有 {a: 1, b: 2}{b: 2, a: 1} 这两个对象,它会返回 false,而实际上应该返回 true - Eric Alberson
3
@EricAlberson,你有没有其他深度比较工具或脚本的建议,可以处理这种情况? - Neil Monroe

8
总的来说,将 $(foo) 与 $(foo) 进行比较是一个不好的主意,因为这等同于以下比较方式:
<html>
<head>
<script language='javascript'>
    function foo(bar) {
        return ({ "object": bar });
    }

    $ = foo;

    if ( $("a") == $("a") ) {
        alert ("JS engine screw-up");
    }
    else {
        alert ("Expected result");
    }

</script>

</head>
</html>

当然,你永远不会期望“JS引擎出错”。我使用“$”只是为了清楚地说明jQuery正在做什么。

每当你调用$("#foo")时,实际上是在执行jQuery("#foo"),它会返回一个新对象。因此,比较它们并期望得到相同的对象是不正确的。

不过,你可以尝试像这样做:

<html>
<head>
<script language='javascript'>
    function foo(bar) {
        return ({ "object": bar });
    }

    $ = foo;

    if ( $("a").object == $("a").object ) {
        alert ("Yep! Now it works");
    }
    else {
        alert ("This should not happen");
    }

</script>

</head>
</html>

因此,您应该比较实际程序中jQuery对象的ID元素,例如:

... 
$(someIdSelector).attr("id") == $(someOtherIdSelector).attr("id")

更适合的是使用

标签。


1
只是为了明确,jQuery没有对象属性。精灵王似乎将其用作伪代码。 - Casebash

6

首先,使用此函数根据键对您的对象进行排序

function sortObject(o) {
    return Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {});
}

然后,使用这个函数比较你的对象的字符串版本。
function isEqualObject(a,b){
    return JSON.stringify(sortObject(a)) == JSON.stringify(sortObject(b));
}

这是一个例子

假设对象的键按不同顺序排序且具有相同的值

var obj1 = {"hello":"hi","world":"earth"}
var obj2 = {"world":"earth","hello":"hi"}

isEqualObject(obj1,obj2);//returns true

4

-1
如果您想检查内容是否相等,只需使用JSON.stringify(obj)
例如 - var a ={key:val};
var b ={key:val}; JSON.stringify(a) == JSON.stringify(b) -----> 如果内容相同,则返回true。

1
你需要先像Kareem的回答一样对键进行排序。 - reggaeguitar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接