равенство объектов jQuery

151

Как определить, равны ли два объекта jQuery? Я хотел бы иметь возможность поиска в массиве для конкретного объекта jQuery.

$.inArray(jqobj, my_array);//-1    
alert($("#deviceTypeRoot") == $("#deviceTypeRoot"));//False
alert($("#deviceTypeRoot") === $("#deviceTypeRoot"));//False
Casebash
источник

Ответы:

225

Начиная с jQuery 1.6, вы можете использовать .is. Ниже приводится ответ более года назад ...

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


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

Если вы хотите увидеть, являются ли две переменные на самом деле одним и тем же объектом, например:

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

... тогда вы можете проверить их уникальные идентификаторы. Каждый раз, когда вы создаете новый объект jQuery, он получает идентификатор.

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
}
nickf
источник
Это решение упрощается до того, которое дает phpdeveloper, когда есть только один элемент. Другой смысл, в котором объекты jQuery можно считать равными, заключается в том, имеют ли они одинаковый селектор и контекст. Это достаточно легко проверить A.selector === B.selector && A.context === B.context. Часто контекст всегда будет одинаковым, поэтому нам нужно рассмотреть только селектор.
Casebash
2
@Casebash - правда, однако учтите, что несколько селекторов могут в конечном итоге получить один и тот же набор результатов, например: $(':first')и$('*:first')
nickf
3
Внимание @rampion и nickf, jQuery is () не проверяет идентичность селекторов , просто они перекрываются. Свидетель: jsfiddle.net/bnhkm/1
Боб Стейн
Ваша equalsфункция, кажется, чувствительна к порядку. что-то вроде stackoverflow.com/a/29648479 будет работать в большем количестве случаев, хотя и медленнее.
Jayen
функция equals работает, только если объект имеет один уровень! сравнение a = b = [{dir: 'test', sort: [{test: {test: 1}}]}] не работает
DavidDunham
16

Если вы все еще не знаете, вы можете вернуть исходный объект:

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

потому что $("#deviceTypeRoot")также возвращает массив объектов, которые селектор выбрал.

mauris
источник
1
Появятся два оповещения true, поскольку вы сравниваете ссылку на элемент DOM, ==vs ===даст вам одинаковые результаты (нет необходимости в приведении типа, это всего лишь две ссылки на объект)
CMS
Ваше второе утверждение на самом деле возвращает True
Casebash
ах да это правда. ошибка копирования и вставки = D
Mauris
14

$.fn.equals(...)Решение, вероятно , самый чистый и самый элегантный один.

Я пробовал что-то быстрое и грязное, как это:

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

Это, вероятно, дорого, но удобно то, что он неявно рекурсивный, а элегантное решение - нет.

Просто мои 2 цента.

Роберто Пьерпаоли
источник
1
это не хорошо для проверки равенства между двумя объектами jQuery, но для стандартных объектов. как "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". мне интересно, что нет jQuery.isEqual (a, b) ...
iRaS
13
Это не верно. Порядок свойств объекта имеет значение. Так что, если у вас есть, {a: 1, b: 2}и {b: 2, a: 1}это вернется, falseкогда он должен вернуться true.
Эрик Альберсон
3
@EricAlberson, есть ли у вас какие-либо предложения относительно других инструментов глубокого сравнения или сценариев, которые могли бы справиться с этой ситуацией?
Нил Монро
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>

Так что на самом деле вам, возможно, следует сравнить элементы ID объектов jQuery в вашей реальной программе, что-то вроде

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

более уместно.

Эльф Кинг
источник
1
Просто чтобы прояснить, у jQuery нет атрибута объекта. Эльф Кинг, кажется, использует это как псевдокод
Casebash
4

Сначала упорядочите ваш объект на основе ключа, используя эту функцию

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
Карима
источник
-1

Если вы хотите проверить, что содержимое равно или нет, просто используйте JSON.stringify (obj)

Например, var a = {key: val};

var b = {key: val};

JSON.stringify (a) == JSON.stringify (b) -----> Если содержимое одинаковое, вы получите истину.

Викрам
источник
Сначала нужно отсортировать ключи, как в ответе Карима
reggaeguitar,