Gleichheit von jQuery-Objekten

151

Wie bestimme ich, ob zwei jQuery-Objekte gleich sind? Ich möchte in der Lage sein, ein Array nach einem bestimmten jQuery-Objekt zu durchsuchen.

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

Antworten:

225

Seit jQuery 1.6 können Sie verwenden .is. Unten ist die Antwort von vor über einem Jahr ...

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


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

Wenn Sie sehen möchten, ob zwei Variablen tatsächlich dasselbe Objekt sind, z.

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

... dann können Sie ihre eindeutigen IDs überprüfen. Jedes Mal, wenn Sie ein neues jQuery-Objekt erstellen, erhält es eine ID.

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

Obwohl das gleiche mit einem einfachen a === berreicht werden könnte, könnte das Obige zumindest dem nächsten Entwickler genau zeigen, worauf Sie testen.

Auf jeden Fall ist das wahrscheinlich nicht das, wonach Sie suchen. Wenn Sie überprüfen möchten, ob zwei verschiedene jQuery-Objekte denselben Satz von Elementen enthalten, können Sie Folgendes verwenden:

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

Quelle

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}
nickf
quelle
Diese Lösung vereinfacht sich zu der vom Entwickler entwickelten, wenn nur ein einziges Element vorhanden ist. Ein weiterer Sinn, in dem jQuery-Objekte als gleich angesehen werden können, ist, ob sie denselben Selektor und Kontext haben. Dies ist leicht zu testen : A.selector === B.selector && A.context === B.context. Oft ist der Kontext immer der gleiche, daher müssen wir nur den Selektor berücksichtigen.
Casebash
2
@Casebash - wahr, aber denken Sie daran, dass mehrere Selektoren mit der gleichen Ergebnismenge enden könnten, zB: $(':first')und$('*:first')
nickf
3
Achtung @rampion und nickf, jQuery is () überprüft nicht, ob Selektoren identisch sind , sondern nur, dass sie sich überlappen. Zeuge: jsfiddle.net/bnhkm/1
Bob Stein
Ihre equalsFunktion scheint auftragsabhängig zu sein. So etwas wie stackoverflow.com/a/29648479 würde in mehr Fällen funktionieren, obwohl es langsamer ist.
Jayen
Die Funktion equals funktioniert nur, wenn das Objekt eine Ebene hat! Vergleichen von a = b = [{dir: 'test', sortieren: [{test: {test: 1}}]}] funktioniert nicht
DavidDunham
16

Wenn Sie es immer noch nicht wissen, können Sie das ursprüngliche Objekt zurückerhalten, indem Sie:

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

da gibt $("#deviceTypeRoot")auch ein Array von Objekten zurück, die der Selektor ausgewählt hat.

Mauris
quelle
1
Die beiden Warnungen werden angezeigt true, da Sie die Referenz des DOM-Elements vergleichen. ==Vs ===gibt Ihnen die gleichen Ergebnisse (kein Typzwang erforderlich, es handelt sich nur um zwei Objektreferenzen)
CMS
Ihre zweite Aussage gibt tatsächlich True
Casebash
Ah ja, es ist wahr. Kopier- und
Einfügefehler
14

Die $.fn.equals(...)Lösung ist wahrscheinlich die sauberste und eleganteste.

Ich habe so etwas schnelles und schmutziges ausprobiert:

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

Es ist wahrscheinlich teuer, aber das Bequeme ist, dass es implizit rekursiv ist, während die elegante Lösung dies nicht ist.

Nur meine 2 Cent.

Roberto Pierpaoli
quelle
1
Dies ist nicht gut für die Überprüfung der Gleichheit zwischen zwei jQuery-Objekten, sondern für Standardobjekte. wie "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". Ich frage mich, dass es keine jQuery.isEqual (a, b) gibt ...
iRaS
13
Das ist falsch. Die Reihenfolge der Objekteigenschaften ist wichtig. Also, wenn Sie haben {a: 1, b: 2}und {b: 2, a: 1}dies wird zurückkehren, falsewenn es zurückkehren sollte true.
Eric Alberson
3
@EricAlberson, haben Sie Vorschläge zu anderen Deep-Compare-Tools oder -Skripten, die mit dieser Situation umgehen könnten?
Neil Monroe
8

Es ist im Allgemeinen eine schlechte Idee, $ (foo) mit $ (foo) zu vergleichen, da dies funktional dem folgenden Vergleich entspricht:

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

Natürlich würde man nie erwarten, dass "JS-Motor versaut". Ich benutze "$", um zu verdeutlichen, was jQuery tut.

Immer wenn Sie $ ("# foo") aufrufen, führen Sie tatsächlich eine jQuery ("# ​​foo") aus, die ein neues Objekt zurückgibt . Es ist also nicht korrekt, sie zu vergleichen und dasselbe Objekt zu erwarten.

Was Sie jedoch tun können, ist Folgendes:

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

Also wirklich sollten Sie vielleicht die ID-Elemente der jQuery-Objekte in Ihrem realen Programm vergleichen, also so etwas wie

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

ist angemessener.

Elfenkönig
quelle
1
Um ganz klar zu sein, hat jQuery kein Objektattribut. Elf King scheint dies als Pseudocode zu verwenden
Casebash
4

Bestellen Sie Ihr Objekt zunächst anhand des Schlüssels mit dieser Funktion

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

Vergleichen Sie dann die stringifizierte Version Ihres Objekts mit dieser Funktion

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

Hier ist ein Beispiel

Angenommen, Objektschlüssel sind unterschiedlich geordnet und haben dieselben Werte

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

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

Wenn Sie überprüfen möchten, ob der Inhalt gleich ist oder nicht, verwenden Sie einfach JSON.stringify (obj).

ZB - var a = {key: val};

var b = {key: val};

JSON.stringify (a) == JSON.stringify (b) -----> Wenn der Inhalt gleich ist, werden Sie wahr.

Vikram
quelle
Sie müssen die Schlüssel zuerst wie
Kareems