Igualdade de objetos jQuery

151

Como determino se dois objetos jQuery são iguais? Gostaria de poder pesquisar uma matriz para um objeto jQuery específico.

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

Respostas:

225

Desde o jQuery 1.6, você pode usar .is. Abaixo está a resposta de mais de um ano atrás ...

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


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

Se você deseja ver se duas variáveis ​​são realmente o mesmo objeto, por exemplo:

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

... então você pode verificar seus IDs exclusivos. Toda vez que você cria um novo objeto jQuery, ele recebe um ID.

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

Embora, o mesmo possa ser alcançado com um simples a === b, o acima pode pelo menos mostrar ao próximo desenvolvedor exatamente o que você está testando.

De qualquer forma, provavelmente não é isso que você procura. Se você quiser verificar se dois objetos jQuery diferentes contêm o mesmo conjunto de elementos, você pode usar isso:

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

Fonte

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}
nickf
fonte
Esta solução simplifica a fornecida pelo thephpdeveloper quando há apenas um único elemento. Outro sentido no qual os objetos jQuery podem ser considerados iguais é se eles têm o mesmo seletor e contexto. Isso é fácil de testar: A.selector === B.selector && A.context === B.context. Muitas vezes, o contexto sempre será o mesmo, portanto, precisamos considerar apenas o seletor.
Casebash 5/07
2
@Casebash - true, no entanto, considere que vários seletores podem acabar com o mesmo conjunto de resultados, por exemplo: $(':first')e$('*:first')
nickf
3
Cuidado @rampion e nickf, jQuery is () não verifica se os seletores são idênticos , apenas se sobrepõem. Testemunha: jsfiddle.net/bnhkm/1
Bob Stein
sua equalsfunção parece ser sensível à ordem. algo como stackoverflow.com/a/29648479 funcionaria em mais casos, embora seja mais lento.
quer
a função igual só funciona se o objeto tiver um nível! comparando a = b = [{dir: 'test', tipo: [{teste: {teste: 1}}]}] não trabalho
DavidDunham
16

Se você ainda não sabe, pode recuperar o objeto original:

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

porque $("#deviceTypeRoot")também retorna uma matriz de objetos que o seletor selecionou.

mauris
fonte
1
Os dois alertas serão exibidos true, porque você está comparando a referência do elemento DOM, ==vs ===lhe dará os mesmos resultados (nenhum tipo de coerção necessários, eles são apenas duas referências de objeto)
CMS
Sua segunda declaração está realmente retornando True
Casebash
ah sim é verdade. Copie e cole
error
14

A $.fn.equals(...)solução é provavelmente a mais limpa e elegante.

Eu tentei algo rápido e sujo como este:

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

Provavelmente é caro, mas o mais confortável é que é implicitamente recursivo, enquanto a solução elegante não é.

Apenas meus 2 centavos.

Roberto Pierpaoli
fonte
1
isso não é bom para verificar a igualdade entre dois objetos jQuery, mas para objetos padrão. como "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". eu estou querendo saber que não há jQuery.isEqual (a, b) ...
IRAS
13
Isto está errado. A ordem das propriedades do objeto é importante. Então, se você tiver {a: 1, b: 2}e {b: 2, a: 1}isso retornará falsequando deve retornar true.
Eric Alberson
3
@ EricAlberson, você tem alguma sugestão sobre outras ferramentas ou scripts de comparação profunda que possam lidar com essa situação?
Neil Monroe
8

Geralmente, é uma má idéia comparar $ (foo) com $ (foo), pois isso é funcionalmente equivalente à seguinte comparação:

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

É claro que você nunca esperaria "erro no motor JS". Eu uso "$" apenas para deixar claro o que o jQuery está fazendo.

Sempre que você chama $ ("# foo"), está realmente fazendo um jQuery ("# ​​foo") que retorna um novo objeto . Portanto, compará-los e esperar o mesmo objeto não está correto.

No entanto, o que você pode fazer é 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>

Então, na verdade, você talvez deva comparar os elementos de identificação dos objetos jQuery no seu programa real, para algo como

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

é mais apropriado.

Elf King
fonte
1
Só para esclarecer, o jQuery não possui um atributo de objeto. Elf King parece estar usando isso como pseudocódigo
Casebash
4

Primeiro ordene seu objeto com base na chave usando esta função

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

Em seguida, compare a versão rigorosa do seu objeto, usando esta função

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

Aqui está um exemplo

Supondo que as chaves dos objetos sejam ordenadas de forma diferente e tenham os mesmos valores

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

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

Se você deseja verificar se o conteúdo é igual ou não, basta usar JSON.stringify (obj)

Por exemplo - var a = {chave: val};

var b = {chave: val};

JSON.stringify (a) == JSON.stringify (b) -----> Se o conteúdo for o mesmo, você será verdadeiro.

Vikram
fonte
Você precisa classificar as chaves primeiro, como a resposta de Kareem
reggaeguitar