Igualdad de objeto jQuery

151

¿Cómo determino si dos objetos jQuery son iguales? Me gustaría poder buscar en una matriz un objeto jQuery particular.

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

Respuestas:

225

Desde jQuery 1.6, puede usar .is. A continuación se muestra la respuesta de hace más de un año ...

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


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

Si desea ver si dos variables son realmente el mismo objeto, por ejemplo:

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

... entonces puedes verificar sus identificaciones únicas. Cada vez que crea un nuevo objeto jQuery, obtiene una identificación.

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

Sin embargo, lo mismo podría lograrse con un simple a === b, lo anterior al menos podría mostrar al próximo desarrollador exactamente lo que está probando.

En cualquier caso, eso probablemente no sea lo que buscas. Si desea verificar si dos objetos jQuery diferentes contienen el mismo conjunto de elementos, puede usar esto:

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

Fuente

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}
nickf
fuente
Esta solución se simplifica a la dada por thephpdeveloper cuando solo hay un único elemento. Otro sentido en el que los objetos jQuery pueden considerarse iguales es si tienen el mismo selector y contexto. Esto es bastante fácil de prueba: A.selector === B.selector && A.context === B.context. A menudo, el contexto siempre será el mismo, por lo que solo tenemos que considerar el selector.
Casebash el
2
@Casebash - cierto, sin embargo, considere que varios selectores podrían terminar con el mismo conjunto de resultados, por ejemplo: $(':first')y$('*:first')
nickf
3
Precaución @rampion y nickf, jQuery is () no verifica que los selectores sean idénticos , simplemente que se superponen. Testigo: jsfiddle.net/bnhkm/1
Bob Stein
su equalsfunción parece ser sensible al orden. algo como stackoverflow.com/a/29648479 funcionaría en más casos, aunque es más lento.
Jayen
¡la función igual solo funciona si el objeto tiene un nivel! comparar a = b = [{dir: 'prueba', ordenar: [{prueba: {prueba: 1}}]}] no funciona
DavidDunham
16

Si aún no lo sabe, puede recuperar el objeto original de la siguiente manera:

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

porque $("#deviceTypeRoot")también devuelve una matriz de objetos que el selector ha seleccionado.

mauris
fuente
1
Se mostrarán las dos alertas true, porque está comparando la referencia del elemento DOM, ==y ===le dará los mismos resultados (no se necesita coerción de tipo, solo son dos referencias de objeto)
CMS
Su segunda declaración es en realidad devolviendo true
Casebash
ah si es verdad. copiar y pegar error = D
mauris
14

La $.fn.equals(...)solución es probablemente la más limpia y elegante.

He intentado algo rápido y sucio como este:

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

Probablemente sea costoso, pero lo cómodo es que es implícitamente recursivo, mientras que la solución elegante no lo es.

Solo mis 2 centavos.

Roberto Pierpaoli
fuente
1
eso no es bueno para verificar la igualdad entre dos objetos jQuery sino para objetos estándar. como "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". Me pregunto si no hay jQuery.isEqual (a, b) ...
iRaS
13
Esto está mal. El orden de las propiedades del objeto es importante. Entonces, si tiene {a: 1, b: 2}y {b: 2, a: 1}esto volverá falsecuando debería volver true.
Eric Alberson
3
@EricAlberson, ¿tiene alguna sugerencia sobre otras herramientas de comparación profunda o scripts que puedan manejar esta situación?
Neil Monroe
8

En general, es una mala idea comparar $ (foo) con $ (foo), ya que es funcionalmente equivalente a la siguiente comparación:

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

Por supuesto, nunca esperarías un "error en el motor JS". Uso "$" solo para dejar en claro lo que está haciendo jQuery.

Cada vez que llamas a $ ("# foo") en realidad estás haciendo un jQuery ("# ​​foo") que devuelve un nuevo objeto . Entonces compararlos y esperar el mismo objeto no es correcto.

Sin embargo, lo que PUEDES hacer puede ser algo como:

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

Entonces, realmente debería comparar los elementos de ID de los objetos jQuery en su programa real para que algo así

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

Es más apropiado.

Rey elfo
fuente
1
Para ser claros, jQuery no tiene un atributo de objeto. Elf King parece estar usando esto como pseudocódigo
Casebash 05 de
4

Primero ordene su objeto basado en la clave usando esta función

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

Luego, compare la versión en cadena de su objeto, utilizando esta función

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

Aquí hay un ejemplo

Asumiendo que las claves de los objetos están ordenadas de manera diferente y tienen los mismos valores

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

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

Si desea verificar que el contenido sea igual o no, simplemente use JSON.stringify (obj)

Por ejemplo, var a = {key: val};

var b = {clave: val};

JSON.stringify (a) == JSON.stringify (b) -----> Si el contenido es el mismo, se vuelve verdadero.

Vikram
fuente
Primero debes ordenar las claves como la respuesta de Kareem
reggaeguitar