Bình đẳng đối tượng jQuery


151

Làm cách nào để xác định xem hai đối tượng jQuery có bằng nhau không? Tôi muốn có thể tìm kiếm một mảng cho một đối tượng jQuery cụ thể.

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

Câu trả lời:


225

Kể từ jQuery 1.6, bạn có thể sử dụng .is. Dưới đây là câu trả lời từ hơn một năm trước ...

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


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

Nếu bạn muốn xem hai biến có thực sự là cùng một đối tượng hay không, vd:

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

... Sau đó bạn có thể kiểm tra ID duy nhất của họ. Mỗi khi bạn tạo một đối tượng jQuery mới, nó sẽ nhận được một id.

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

Mặc dù, điều tương tự có thể đạt được với một cách đơn giản a === b, nhưng ở trên ít nhất có thể hiển thị cho nhà phát triển tiếp theo chính xác những gì bạn đang thử nghiệm.

Trong mọi trường hợp, đó có lẽ không phải là những gì bạn đang theo đuổi. Nếu bạn muốn kiểm tra xem hai đối tượng jQuery khác nhau có chứa cùng một bộ phần tử hay không, thì bạn có thể sử dụng điều này:

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

Nguồn

var a = $('p');
var b = $('p');
if (a.equals(b)) {
    // same set
}

Giải pháp này đơn giản hóa với giải pháp được đưa ra bởi nhà phát triển khi chỉ có một yếu tố duy nhất. Một ý nghĩa khác trong đó các đối tượng jQuery có thể được coi là bằng nhau là liệu chúng có cùng bộ chọn và ngữ cảnh hay không. Điều này là đủ dễ dàng để kiểm tra : A.selector === B.selector && A.context === B.context. Thường thì bối cảnh sẽ luôn giống nhau, vì vậy chúng ta chỉ phải xem xét bộ chọn.
Casebash

2
@Casebash - đúng, tuy nhiên, hãy xem xét rằng một số bộ chọn có thể kết thúc với cùng một tập kết quả, ví dụ: $(':first')$('*:first')
nickf

3
Thận trọng @rampion và nickf, jQuery là () không kiểm tra các bộ chọn giống hệt nhau , chỉ đơn thuần là chúng trùng nhau. Nhân chứng: jsfiddle.net/bnhkm/1
Bob Stein

equalschức năng của bạn có vẻ nhạy cảm với trật tự. một cái gì đó như stackoverflow.com/a/29648479 sẽ hoạt động trong nhiều trường hợp hơn, mặc dù nó chậm hơn.
Jayen

Hàm bằng chỉ hoạt động nếu đối tượng có một cấp! so sánh a = b = [{dir: 'test', sort: [{test: {test: 1}}]}] không hoạt động
DavidDunham

16

Nếu bạn vẫn không biết, bạn có thể lấy lại đối tượng ban đầu bằng cách:

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

bởi vì $("#deviceTypeRoot")cũng trả về một mảng các đối tượng mà bộ chọn đã chọn.


1
Hai cảnh báo sẽ hiển thị true, bởi vì bạn đang so sánh tham chiếu của phần tử DOM, ==vs ===sẽ cho bạn kết quả giống nhau (không cần ép buộc kiểu, chúng chỉ là hai tham chiếu đối tượng)
CMS

Tuyên bố thứ hai của bạn đang thực sự trở lại Đúng
Casebash

à vâng đúng vậy sao chép và dán lỗi = D
mauris

14

Các $.fn.equals(...)giải pháp có lẽ là một trong sạch và thanh lịch nhất.

Tôi đã thử một cái gì đó nhanh chóng và bẩn thỉu như thế này:

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

Nó có thể là đắt tiền, nhưng điều thoải mái là nó được đệ quy ngầm, trong khi giải pháp thanh lịch thì không.

Chỉ cần 2 xu của tôi.


1
Điều đó không tốt cho việc kiểm tra sự bằng nhau giữa hai đối tượng jQuery nhưng đối với các đối tượng tiêu chuẩn. như "{a: 'x', b: 'y', c: 'z'} == {a: 'x', b: 'y', c: 'z'}". Tôi đang tự hỏi rằng không có jQuery.isEqual (a, b) ...
iRaS

13
Cái này sai. Thứ tự của các thuộc tính đối tượng quan trọng. Vì vậy, nếu bạn có {a: 1, b: 2}{b: 2, a: 1}điều này sẽ trở lại falsekhi nó nên trở lại true.
Eric Alberson

3
@EricAlberson, bạn có đề xuất nào về các công cụ hoặc tập lệnh so sánh sâu khác có thể xử lý tình huống này không?
Neil Monroe

8

Nói chung, đó là một ý tưởng tồi để so sánh $ (foo) với $ (foo) vì nó tương đương về mặt chức năng với so sánh sau:

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

Tất nhiên, bạn sẽ không bao giờ mong đợi "vặn động cơ JS". Tôi sử dụng "$" chỉ để làm rõ jQuery đang làm gì.

Bất cứ khi nào bạn gọi $ ("# foo"), bạn thực sự đang thực hiện một jQuery ("# ​​foo") để trả về một đối tượng mới . Vì vậy, so sánh chúng và mong đợi cùng một đối tượng là không chính xác.

Tuy nhiên, những gì bạn CÓ THỂ làm có thể là một cái gì đó như:

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

Vì vậy, thực sự có lẽ bạn nên so sánh các thành phần ID của các đối tượng jQuery trong chương trình thực của bạn để một cái gì đó như

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

là phù hợp hơn.


1
Rõ ràng, jQuery không có thuộc tính đối tượng. Vua Elf dường như đang sử dụng điều này như mã giả
Casebash


4

Đầu tiên đặt hàng đối tượng của bạn dựa trên khóa sử dụng chức năng này

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

Sau đó, so sánh phiên bản được xâu chuỗi của đối tượng của bạn, sử dụng chức năng này

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

Đây là một ví dụ

Giả sử các khóa đối tượng được sắp xếp khác nhau và có cùng giá trị

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

isEqualObject(obj1,obj2);//returns true

-1

Nếu bạn muốn kiểm tra nội dung có bằng nhau hay không thì chỉ cần sử dụng JSON.opesify (obj)

Ví dụ: var a = {key: val};

var b = {key: val};

JSON.opesify (a) == JSON.opesify (b) -----> Nếu nội dung giống nhau, bạn sẽ đúng.


Bạn cần sắp xếp các phím trước như câu trả lời của Kareem
reggaeg Ức
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.