Égalité des objets jQuery

151

Comment déterminer si deux objets jQuery sont égaux? Je voudrais pouvoir rechercher un tableau pour un objet jQuery particulier.

$.inArray(jqobj, my_array);//-1    
alert($("#deviceTypeRoot") == $("#deviceTypeRoot"));//False
alert($("#deviceTypeRoot") === $("#deviceTypeRoot"));//False
Casebash
la source

Réponses:

225

Depuis jQuery 1.6, vous pouvez utiliser .is. Voici la réponse d'il y a plus d'un an ...

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


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

Si vous voulez voir si deux variables sont réellement le même objet, par exemple:

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

... alors vous pouvez vérifier leurs identifiants uniques. Chaque fois que vous créez un nouvel objet jQuery, il obtient un identifiant.

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

Bien que la même chose puisse être obtenue avec un simple a === b, ce qui précède pourrait au moins montrer au prochain développeur exactement ce que vous testez.

En tout cas, ce n'est probablement pas ce que vous recherchez. Si vous souhaitez vérifier si deux objets jQuery différents contiennent le même ensemble d'éléments, vous pouvez utiliser ceci:

$.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;
};

La source

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}
nickf
la source
Cette solution se simplifie à celle donnée par le développeur php lorsqu'il n'y a qu'un seul élément. Un autre sens dans lequel les objets jQuery peuvent être considérés comme égaux est de savoir s'ils ont le même sélecteur et le même contexte. Ceci est assez facile à tester: A.selector === B.selector && A.context === B.context. Souvent, le contexte sera toujours le même, il suffit donc de considérer le sélecteur.
Casebash
2
@Casebash - vrai, mais considérez que plusieurs sélecteurs pourraient aboutir au même jeu de résultats, par exemple: $(':first')et$('*:first')
nickf
3
Attention @rampion et nickf, jQuery is () ne vérifie pas que les sélecteurs sont identiques , mais simplement qu'ils se chevauchent. Témoin: jsfiddle.net/bnhkm/1
Bob Stein
votre equalsfonction semble être sensible à l'ordre. quelque chose comme stackoverflow.com/a/29648479 fonctionnerait dans plus de cas, bien que ce soit plus lent.
Jayen
la fonction égal ne fonctionne que si l'objet a un niveau! comparer a = b = [{dir: 'test', sort: [{test: {test: 1}}]}] ne fonctionne pas
DavidDunham
16

Si vous ne savez toujours pas, vous pouvez récupérer l'objet d'origine en:

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

car $("#deviceTypeRoot")renvoie également un tableau d'objets que le sélecteur a sélectionnés.

Mauris
la source
1
Les deux alertes s'afficheront true, car vous comparez la référence de l'élément DOM, ==vs ===vous donneront les mêmes résultats (aucune contrainte de type nécessaire, ce ne sont que deux références d'objet)
CMS
Votre deuxième déclaration est en fait de retour True
Casebash
ah oui c'est vrai. copier et coller erreur = D
mauris
14

La $.fn.equals(...)solution est probablement la plus propre et la plus élégante.

J'ai essayé quelque chose de rapide et sale comme celui-ci:

JSON.stringify(a) == JSON.stringify(b)

C'est probablement cher, mais ce qui est confortable, c'est qu'il est implicitement récursif, alors que la solution élégante ne l'est pas.

Juste mes 2 cents.

Roberto Pierpaoli
la source
1
ce n'est pas bon pour vérifier l'égalité entre deux objets jQuery mais pour les objets standard. comme "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". je me demande qu'il n'y a pas de jQuery.isEqual (a, b) ...
iRaS
13
C'est faux. L'ordre des propriétés de l'objet est important. Donc, si vous avez {a: 1, b: 2}et {b: 2, a: 1}cela reviendra falsequand il devrait revenir true.
Eric Alberson
3
@EricAlberson, avez-vous des suggestions sur d'autres outils ou scripts de comparaison approfondie qui pourraient gérer cette situation?
Neil Monroe
8

C'est, d'une manière générale, une mauvaise idée de comparer $ (foo) avec $ (foo) car cela est fonctionnellement équivalent à la comparaison suivante:

<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>

Bien sûr, vous ne vous attendriez jamais à une "erreur du moteur JS". J'utilise "$" juste pour clarifier ce que fait jQuery.

Chaque fois que vous appelez $ ("# foo"), vous faites en fait un jQuery ("# ​​foo") qui renvoie un nouvel objet . Donc, les comparer et attendre le même objet n'est pas correct.

Cependant, ce que vous POUVEZ faire peut être quelque chose comme:

<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>

Donc, vraiment, vous devriez peut-être comparer les éléments ID des objets jQuery dans votre programme réel, donc quelque chose comme

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

est plus approprié.

Roi elfe
la source
1
Pour être clair, jQuery n'a pas d'attribut d'objet. Elf King semble l'utiliser comme pseudocode
Casebash
4

Commencez par commander votre objet en fonction de la clé en utilisant cette fonction

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

Ensuite, comparez la version stringifiée de votre objet, en utilisant cette fonction

function isEqualObject(a,b){
    return JSON.stringify(sortObject(a)) == JSON.stringify(sortObject(b));
}

Voici un exemple

En supposant que les clés des objets sont ordonnées différemment et ont les mêmes valeurs

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

isEqualObject(obj1,obj2);//returns true
Kareem
la source
-1

Si vous voulez vérifier que le contenu est égal ou non, utilisez simplement JSON.stringify (obj)

Par exemple - var a = {clé: val};

var b = {clé: val};

JSON.stringify (a) == JSON.stringify (b) -----> Si le contenu est le même, vous obtenez vrai.

Vikram
la source
Vous devez d'abord trier les clés comme la réponse de Kareem
reggaeguitar