2010-09-29 33 views
5

Tại sao mã sau cần thêm () cho eval?Tại sao chúng ta cần phải thêm dấu ngoặc đơn để đánh giá JSON?

var strJson = eval("(" + $("#status").val().replace(";","") + ")"); 

PS: $("#status").val() đang trở lại một cái gì đó giống như {"10000048":"1","25000175":"2","25000268":"3"};

+0

Tại sao bạn sử dụng 'eval' ngay từ đầu? Chỉ cần gắn bó với: 'var strJson = $ (" # status "). Val(). Replace ("; "," ");' –

Trả lời

3

eval mất một tuyên bố hoặc biểu thức JavaScript, nhưng {...} sẽ có giá trị như một tuyên bố hoặc một biểu thức và ngữ pháp của JavaScript thích một tuyên bố.

Như một biểu:

{"10000048":"1","25000175":"2","25000268":"3"} 

là một đối tượng với một số tài sản (những gì bạn muốn).

Như một tuyên bố, nó là một khối:

{      // begin Block 
    "10000048":   // LabelledStatement (but the quotes are invalid) 
     "1",   // Expression, calculate string "1" then discard it, then 
      "25000175": // you can't put a label inside an expression 

mang đến cho một lỗi.

(nhãn JavaScript có thể được sử dụng để đặt tên một tuyên bố đặc biệt để sử dụng với break/continue. Họ là một chút vô nghĩa và hầu như không bao giờ sử dụng.)

Vì vậy, bằng cách thêm dấu ngoặc bạn giải quyết sự mơ hồ. Chỉ một biểu thức có thể bắt đầu bằng (, do đó nội dung được phân tích cú pháp trong ngữ cảnh biểu thức, cho một đối tượng theo nghĩa đen chứ không phải ngữ cảnh câu lệnh.

Ngẫu nhiên, đây không phải là khá đủ để diễn giải chính xác tất cả các giá trị JSON có thể có. Do giám sát trong thiết kế của JSON, các ký tự U + 2028 và U + 2029, hai ký tự cuối dòng Unicode tối nghĩa, có giá trị để đặt không thoát trong một chuỗi JSON theo nghĩa đen, nhưng không phải trong chuỗi ký tự JavaScript.Nếu bạn muốn an toàn, bạn có thể trốn thoát chúng, ví dụ:

function parseJSON(s) { 
    if ('JSON' in window) return JSON.parse(s); 
    return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')'); 
} 
4

Nó phụ thuộc những gì giá trị trong phần tử đó là (một người vô danh), gói nó trong () là con đường an toàn để chiếm thể của không đầu vào ở đó.

Edit: Bây giờ bạn đã xoá sổ nó JSON, đây là không hợp lệ:

eval('{"10000048":"1","25000175":"2","25000268":"3"}'); 

Nhưng điều này sẽ dẫn đến một đối tượng có giá trị được trả về:

eval('({"10000048":"1","25000175":"2","25000268":"3"})'); 
//effectively: 
eval('return {"10000048":"1","25000175":"2","25000268":"3"};'); 

Ảnh trong một Tệp JavaScript:

<script type="text/javascript"> 
    {"10000048":"1","25000175":"2","25000268":"3"} 
</script> 

Điều này sẽ thất bại, nó chỉ là một đối tượng được khai báo nội tuyến nhưng không đúng cú pháp ... cùng một lý do máy chủ để hỗ trợ JSONP hoạt động.


Một chút tiếp tuyến với các câu hỏi, nhưng kể từ khi bạn bao gồm jQuery, bạn cũng có thể sử dụng $.parseJSON() (mà sẽ sử dụng bản địa JSON.parse() nếu có) cho việc này:

var strJson = $.parseJSON($("#status").val().replace(";","")); 
+0

Xin chào val() trả lại là một cái gì đó như {"10000048": "1 "," 25000175 ":" 2 "," 25000268 ":" 3 "}; – Ricky

+0

tại sao câu lệnh đầu tiên không hợp lệ – Ricky

+0

@Ricky - Cú pháp này không hợp lệ vì cùng một lý do không trực tiếp trong tập lệnh, vì trình phân tích cú pháp không xem nó như là một biểu thức trong khi thêm '()' một cách hiệu quả (vì nó chuyển sang một biểu thức, nhận ra '{' như là một đối tượng bắt đầu, nhận/trả về đối tượng mà bạn quan tâm). –

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