jQuery рівність об'єкта


151

Як визначити, чи рівні два об'єкти jQuery? Я хотів би мати можливість пошуку масиву для певного об’єкта jQuery.

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

Відповіді:


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
}

Це рішення спрощується до рішення, яке надає thephpdeveloper, коли є лише один елемент. Інший сенс, в якому об'єкти jQuery можна вважати рівними, - чи мають вони однаковий селектор і контекст. Це досить просто для перевірки: A.selector === B.selector && A.context === B.context. Часто контекст завжди буде однаковим, тому нам залишається лише враховувати селектор.
Casebash

2
@Casebash - правда, проте врахуйте, що декілька селекторів можуть отримати один і той же набір результатів, наприклад: $(':first')і$('*:first')
nickf

3
Застереження @rampion та nickf, jQuery не () не перевіряє, чи є селектори однакові , а лише те, що вони перетинаються. Свідок: jsfiddle.net/bnhkm/1
Боб Штейн

equalsздається, ваша функція залежить від порядку. щось на зразок stackoverflow.com/a/29648479 працювало б у більшості випадків, хоча це повільніше.
Jayen

функція рівняння працює лише в тому випадку, якщо об’єкт має один рівень! порівняння a = b = [{dir: 'test', сортування: [{test: {test: 1}}]}] не працює
DavidDunham

16

Якщо ви все ще не знаєте, ви можете повернути оригінальний об'єкт за допомогою:

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

тому що $("#deviceTypeRoot")також повертає масив об'єктів, який вибрав селектор.


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 не має атрибута об'єкта. Elf King, здається, використовує це як псевдокод
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 = {ключ: val};

var b = {ключ: val};

JSON.stringify (a) == JSON.stringify (b) -----> Якщо вміст однаковий, ви станете справжнім.


Спершу вам потрібно відсортувати ключі, як відповідь Карема
reggaeguitar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.