2009-06-08 22 views
33

Tôi đã học được (cách cứng) mà tôi cần phải thêm dấu ngoặc xung quanh dữ liệu JSON, như thế này:Tại sao eval của JavaScript cần dấu ngoặc đơn để đánh giá dữ liệu JSON?

stuff = eval('(' + data_from_the_wire + ')'); 
// where data_from_the_wire was, for example {"text": "hello"} 

(Trong Firefox 3, ít nhất).

Lý do đằng sau điều này là gì? Tôi ghét viết mã mà không hiểu những gì đằng sau mui xe.

+1

Tôi thấy bạn không phải là người nói tiếng Anh bản địa nhưng '(' và ')' là dấu ngoặc đơn. Nó có thể giúp những người khác tìm thấy bài đăng của bạn nếu bạn sửa lỗi này. –

Trả lời

38

Đưa ngoặc xung quanh data_from_the_wire được hiệu quả tương đương với

stuff = eval('return ' + data_from_the_wire + ';'); 

Nếu bạn đã eval mà không có dấu ngoặc đơn, sau đó mã sẽ được đánh giá, và nếu bạn đã có bất kỳ chức năng đặt tên bên trong nó những sẽ được xác định , nhưng không được trả lại.

Hãy làm ví dụ khả năng để gọi một chức năng chỉ vì nó được tạo ra han:

(function() { alert('whoot'); })() 

sẽ gọi hàm vừa được xác định. Tuy nhiên, những điều sau đây không hoạt động:

function() { alert('whoot'); }() 

Vì vậy, chúng tôi thấy rằng dấu ngoặc đơn hiệu quả chuyển thành mã biểu thức trả về, thay vì chỉ chạy mã.

+3

+1 Giải thích rất rõ ràng. Cảm ơn. –

+1

+1 vì lý do tương tự như Oliver :) – Stefan

+4

Phần đầu tiên không chính xác; eval giải thích chuỗi là mã cấp cao nhất, vì vậy việc trả về không hoạt động. Vấn đề với chức năng tương tự như câu hỏi ban đầu, bởi vì đó là sự mơ hồ giữa hàm * tuyên bố * và biểu thức hàm * (xem câu trả lời của câu trả lời của karim79). –

-2

Tôi không biết, và tôi thực sự quan tâm đến câu trả lời cho điều này, nhưng tôi đoán là nếu không có dấu ngoặc đơn, dữ liệu trong data_from_the_wire sẽ được hiểu là đóng. Có lẽ các dấu ngoặc đơn buộc đánh giá và do đó mảng kết hợp là 'trả về'.

Đây là loại phỏng đoán dẫn đến downvotes mặc dù =).

EDIT

Douglas Crockford đề cập đến một sự mơ hồ cú pháp trên trang web JSON mình nhưng điều đó không thực sự giúp tôi.

10

Tôi không chắc chắn lý do nhưng tôi phân tích cú pháp JSON bằng cách sử dụng the JSON class từ json.org. Nó an toàn hơn nhiều so với việc sử dụng eval.

+5

Tại sao lại là downvote? Dường như câu trả lời hợp lệ. Sử dụng eval không an toàn. –

+0

Anh ấy không hỏi cách sử dụng eval đúng cách để phân tích cú pháp JSON, anh ấy hỏi tại sao cần có dấu ngoặc đơn. –

+2

@ TimČas Tôi nhận ra tôi không trả lời câu hỏi trực tiếp nhưng khi ai đó chĩa súng vào chân họ và hỏi tại sao họ cần loại bỏ sự an toàn, trước tiên tôi khuyên họ chỉ một khẩu súng ở chân có thể không phải là một ý tưởng tuyệt vời. –

62

eval chấp nhận một chuỗi các câu lệnh Javascript. Trình phân tích cú pháp Javascript diễn giải mã thông báo ‘{’, xảy ra trong một tuyên bố là bắt đầu của một khối và không phải là bắt đầu của một đối tượng theo nghĩa đen.

Khi bạn đính kèm chữ vào ngoặc đơn như sau: ({ data_from_the_wire }) bạn đang chuyển trình phân tích cú pháp Javascript thành chế độ phân tích biểu thức. Mã thông báo ‘{’ bên trong một biểu thức có nghĩa là bắt đầu khai báo đối tượng bằng chữ và không phải là một khối và do đó Javascript chấp nhận nó dưới dạng đối tượng theo nghĩa đen.

2

Điều này xảy ra vì không có dấu ngoặc tròn JavaScript cố gắng diễn giải {"text": ...a label và không thành công. Hãy dùng thử trong bảng điều khiển và bạn sẽ nhận được lỗi "nhãn không hợp lệ".

1

Tùy thuộc vào giá trị thực tế là data_from_the_wire. Trong hầu hết các trường hợp, cú pháp của bạn là ok, nhưng một dòng bắt đầu bằng { được phân tích cú pháp dưới dạng nhãn và của bạn không hợp lệ.Nếu bạn bao quanh dấu ngoặc đơn, dấu ngoặc đơn sẽ ngăn trình phân tích cú pháp giải thích sai biểu thức của bạn.

Chỉ là một vấn đề phân tích cú pháp. Với chuỗi, số hoặc chức năng, bạn sẽ không gặp phải vấn đề đó.

Một giải pháp là luôn luôn đánh giá hướng dẫn chứ không phải biểu thức. Bạn có thể viết

eval('var stuff = {"text": "hello"}'); 
9

Trong JavaScript, dấu ngoặc nhọn được sử dụng để tạo báo cáo khối:

{ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(); 
} 

Các dòng trên có thể được đặt bên trong một chuỗi và eval uated mà không vấn đề. Bây giờ xem xét việc này:

{ 
"foo": "bar", 
"blah": "baz" 
} 

Các dấu ngoặc nhọn gây ra động cơ Javascript để nghĩ rằng đó là một biểu thức nhóm, vì thế mà lỗi cú pháp xung quanh nhân vật :. Trích dẫn từ MDN...JavaScript Guide...Object Literals:

Bạn không nên sử dụng đối tượng bằng chữ ở đầu câu lệnh. Điều này sẽ dẫn đến lỗi hoặc không hoạt động như bạn mong đợi, vì { sẽ được hiểu là sự bắt đầu của một khối.

Cách khắc phục đối tượng để xử lý nội dung của nó dưới dạng biểu thức, chứ không phải là câu lệnh chặn. Vì vậy, điều này không làm việc:

({ 
var foo = "bar"; 
var blah = "baz"; 
doSomething(evil); 
}) 
// parse error 

Nhưng điều này không:

({ 
"foo": "bar", 
"blah": "baz" 
}) 
// returns object 
Các vấn đề liên quan