2013-03-13 56 views
9

Sau khi cố gắng một số triển khai để đối chiếu sâu và sao chép cho JSON-serializable đối tượng, tôi đã nhận thấy nhanh nhất thường chỉ:Bạn có sử dụng JSON.stringify để so sánh sâu và nhân bản không?

function deep_clone(a){ 
    return JSON.parse(JSON.stringify(a)); 
}; 
function is_equal(a,b){ 
    return JSON.stringify(a) === JSON.stringify(b); 
}; 

tôi cảm thấy như thế này là lừa dối, mặc dù. Giống như tôi sẽ tìm thấy một số vấn đề mà sẽ làm phiền tôi trong tương lai. Sử dụng chúng có tốt không?

+1

Tôi chỉ sử dụng các đối tượng có thể tuần tự hóa JSON. – MaiaVictor

+1

Bài viết FWIW nghiêm ngặt về việc nói 'đối tượng JSON' và nói rằng không có thứ như 'đối tượng JSON' http://benalman.com/news/2010/03/theres-no-such-thing-as-a- json/ – DanC

+0

@BenjaminGruenbaum không hoàn toàn trùng lặp, nhưng những kẻ đó đang sử dụng thư viện JSON cũ. – MaiaVictor

Trả lời

9

JavaScript không đảm bảo thứ tự các khóa.

Nếu chúng được nhập theo thứ tự như nhau, phương pháp này sẽ hoạt động phần lớn thời gian, nhưng sẽ không đáng tin cậy.

Ngoài ra, nó sẽ trả về false cho các đối tượng đó là sâu sắc như nhau, nhưng có các phím được nhập theo một thứ tự khác nhau:

JSON.stringify ({a: 1, b: 2}) === "{ "a": 1, "b": 2} "

JSON.stringify ({b: 2, a: 1}) ===" {"b": 2, "a": 1} "

+1

Đúng. Điều đó làm cho câu trả lời khác sai. Đã đánh dấu chọn. – MaiaVictor

2

Miễn là cặp khóa-giá trị luôn theo cùng thứ tự, có, bạn có thể sử dụng xâu chuỗi để so sánh bằng toán tử bằng (===).

4

Tôi nhận ra đó là một câu hỏi cũ, nhưng tôi chỉ muốn thêm một chút vào câu trả lời, vì ai đó có thể rời khỏi trang này nhầm lẫn nghĩ rằng sử dụng JSON.stringify để so sánh/nhân bản sẽ hoạt động mà không có vấn đề miễn là nó không không được sử dụng để so sánh/sao chép các đối tượng có các thành viên không có thứ tự. (Để công bằng với câu trả lời được chấp nhận, họ không nên bỏ đi nghĩ rằng, "Nếu [các thành viên] được nhập theo cùng một thứ tự, phương pháp này sẽ hoạt động hầu hết thời gian.")

Mã lẽ minh họa trục trặc tiềm năng tốt nhất:

JSON.stringify(NaN) === JSON.stringify(null) 
// => true 

JSON.stringify(Infinity) === JSON.stringify(null) 
// => true 

// or, to put it all together: 
JSON.stringify({ val1: (1/0), val2: parseInt("hi there"), val3: NaN }) === JSON.stringify({ val1: NaN, val2: null, val3: null }) 
// => true 

// and here's the same example with "cloning" rather than comparison: 
JSON.parse(JSON.stringify({ val1: (1/0), val2: parseInt("hi there"), val3: NaN })) 
// => Object {val1: null, val2: null, val3: null} 

Đây là những đôi mà có thể gây ra rắc rối ngay cả khi đặt hàng không phải là một vấn đề (trong đó, như những người khác đã nói, nó có thể được). Nó có thể không có khả năng trong hầu hết các trường hợp những quirks sẽ phía sau đầu xấu xí của họ, nhưng nó là tốt để được nhận thức của họ, vì họ có thể dẫn đến một số thực sự khó khăn để tìm lỗi.

+0

Cảm ơn bạn đã bổ sung! – MaiaVictor