2011-10-10 56 views
5

Sau đây là thực hiện trong Firebug:Trong Javascript, tại sao [1, 2] == [1, 2] hoặc ({a: 1}) == ({a: 1}) sai?

>>> [1, 2] == [1, 2] 
false 

>>> ({a : 1}) == ({a : 1}) 
false 

Tôi nghĩ javscript có một số nguyên tắc mà nói, nếu một đối tượng hoặc mảng có tài liệu tham khảo cùng với các yếu tố tương tự, sau đó họ đều bình đẳng?

Nhưng ngay cả khi tôi nói

>>> foo = {a : 1} 
Object { a=1} 

>>> [foo] == [foo] 
false 

>>> ({a: foo}) == ({a: foo}) 
false 

Có cách nào để làm cho nó để nó có thể làm việc so sánh phần tử và trở true?

+12

đối tượng literals tạo các phiên bản mới, xác định hai trường hợp không làm cho chúng chia sẻ cùng một tham chiếu. – zzzzBov

+0

nó không phải là "yếu tố bên trong" cần phải bằng nhau? –

Trả lời

6

{ }[ ] cũng giống như new Objectnew Array

new Object != new Object (ditto với Array), vì họ là mới và khác nhau đối tượng.

Nếu bạn muốn biết liệu nội dung của hai đối tượng tùy ý là "cùng" đối với một số giá trị của cùng sau đó một sửa chữa nhanh chóng (nhưng chậm) là

JSON.parse(o) === JSON.parse(o)

Một giải pháp thanh lịch hơn sẽ để xác định một chức năng tương đương (chưa được kiểm tra)

var equal = function _equal(a, b) { 
    // if `===` or `==` pass then short-circuit 
    if (a === b || a == b) { 
    return true; 
    } 
    // get own properties and prototypes 
    var protoA = Object.getPrototypeOf(a), 
     protoB = Object.getPrototypeOf(b), 
     keysA = Object.keys(a), 
     keysB = Object.keys(b); 

    // if protos not same or number of properties not same then false 
    if (keysA.length !== keysB.length || protoA !== protoB) { 
    return false; 
    } 
    // recurse equal check on all values for properties of objects 
    return keysA.every(function (key) { 
    return _equal(a[key], b[key]); 
    }); 
}; 

equals example

Cảnh báo: viết một hàm bình đẳng mà "hoạt động" trên tất cả các yếu tố đầu vào là khó, một số gotchas phổ biến là (null == undefined) === true(NaN === NaN) === false cả hai đều không gaurd cho chức năng của tôi.

Tôi cũng không giải quyết được bất kỳ vấn đề nào về trình duyệt chéo, tôi vừa giả định ES5 tồn tại.

+0

'! =='! == '!= ';-) –

+0

Bạn có rất nhiều thứ để vá với hàm đó. Ví dụ. 'bằng ({}, {}) === false'. Ngoài ra, tôi nghĩ rằng bạn có nghĩa là để recurse với '_equal'. – davin

+0

@davin '_equal' chỉ là một quy ước và tôi không biết cách xử lý' {} 'và' [] 'một cách tao nhã. Điều đó cũng đặt câu hỏi liệu có bằng nhau (Object.create (foo), Object.create (bar)) 'phải đúng hay sai. – Raynos

0

Vì các đối tượng javascript của nó không chia sẻ cùng một con trỏ. Thay vào đó, một con trỏ mới sẽ được tạo cho mỗi con trỏ. Hãy xem xét ví dụ sau:

>>> ({a : 1}) == ({a : 1}) 
false 

... nhưng ...

>>> obj = ({a : 1}); 
Object 

>>> obj == obj 
true 

obj là một con trỏ đến đối tượng litteral { a : 1 }. Vì vậy, điều này hoạt động vì các con trỏ giống nhau khi bạn so sánh chúng với nhau

0

Bạn đang so sánh các đối tượng khác nhau.

>>> var a = [1,2] var b = [1,2] 
>>> a == b 
false 
>>> a == a 
true 

Nếu bạn muốn kiểm tra sự bình đẳng mảng, bạn có thể muốn sử dụng một số thư viện hoặc chỉ tự viết bài kiểm tra.

2

Để xem loại mã nào cần thiết để thực hiện bình đẳng sâu bạn đang nói đến, hãy xem Underscore.js's _.isEqual function hoặc QUnit's deepEqual implementation.

+0

Là nguồn của '_' và' QUnit' chỉ ra, deepEquality là một điều không quan trọng để làm. – Raynos

+0

Khi bạn nhanh chóng tìm ra câu trả lời của mình;) – Domenic

+0

Tôi nghĩ nỗ lực ES5 của tôi là thanh lịch và bao gồm 99% số trường hợp sử dụng! – Raynos

Các vấn đề liên quan