Các khóa JSON có phải được bao quanh bởi dấu ngoặc kép không?


233

Ví dụ: Mã sau có hợp lệ với Spec Spec không?

{
    precision: "zip"
}

Hoặc tôi nên luôn luôn sử dụng cú pháp sau đây? (Và nếu vậy, tại sao?)

{
    "precision": "zip"
}

Tôi chưa thực sự tìm thấy điều gì về điều này trong các đặc tả JSON. Mặc dù họ sử dụng dấu ngoặc kép quanh các khóa của họ trong ví dụ của họ.

Câu trả lời:


145

Có, bạn cần dấu ngoặc kép. Điều này là để làm cho nó đơn giản hơn và để tránh phải có một phương thức thoát khác cho các từ khóa dành riêng cho javascript, tức là {for:"foo"}.


12
Các trích dẫn không đơn giản hơn trong nhiều tình huống, chẳng hạn như các tệp cấu hình được chỉnh sửa bằng tay. Điều không may về việc JSON được sử dụng (và sử dụng sai) như một định dạng trao đổi gần như phổ biến là nó có các tính năng dành riêng cho Javascript.
miguel

12
Lý do thực sự - cũng kiểm tra câu trả lời này - stackoverflow.com/questions/4201441/ cấp
TechMaze

3
Tl; dr: họ không muốn đối phó với giới hạn ECMAScript đối với các từ khóa dành riêng (không trích dẫn) dưới dạng khóa, vì vậy họ chỉ yêu cầu trích dẫn tất cả các khóa.
BallpointBen

136

Bạn đúng khi sử dụng chuỗi làm khóa. Đây là một đoạn trích từ RFC 4627 - Loại phương tiện ứng dụng / json cho Ký hiệu đối tượng JavaScript (JSON)

2.2. Các đối tượng

Một cấu trúc đối tượng được biểu diễn dưới dạng một cặp dấu ngoặc nhọn bao quanh 0 hoặc nhiều cặp tên / giá trị (hoặc thành viên). Một tên là một chuỗi . Một dấu hai chấm xuất hiện sau mỗi tên, tách tên khỏi giá trị. Dấu phẩy đơn tách một giá trị từ một tên sau. Tên trong một đối tượng NÊN là duy nhất.

object = begin-object [ member *( value-separator member ) ] end-object

member = string name-separator value

[...]

2.5. Dây

Việc biểu diễn các chuỗi tương tự như các quy ước được sử dụng trong họ ngôn ngữ lập trình C. Một chuỗi bắt đầu và kết thúc bằng dấu ngoặc kép. [...]

string = quotation-mark *char quotation-mark

quotation-mark = %x22 ; "

Đọc toàn bộ RFC ở đây .


11
Và để kết thúc suy nghĩ, phần 2.5 nói : A string begins and ends with quotation marks..
rakslice

13

Từ 2.2. Các đối tượng

Một cấu trúc đối tượng được biểu diễn dưới dạng một cặp dấu ngoặc nhọn bao quanh 0 hoặc nhiều cặp tên / giá trị (hoặc thành viên). Một tên là một chuỗi.

và từ 2.5. Dây

Một chuỗi bắt đầu và kết thúc bằng dấu ngoặc kép.

Vì vậy, tôi sẽ nói rằng theo tiêu chuẩn: có, bạn phải luôn trích dẫn khóa (mặc dù một số trình phân tích cú pháp có thể dễ tha thứ hơn)


7

Có, trích dẫn là bắt buộc. http://json.org/ nói:

string
    ""
    " chars "

0

Có họ làm. Nhưng nếu bạn cần khác, hãy kiểm tra JSON5 .

JSON5 là một siêu bộ JSON cho phép cú pháp ES5, bao gồm:

  • khóa thuộc tính không trích dẫn
  • chuỗi trích dẫn đơn, thoát và nhiều dòng
  • định dạng số thay thế
  • bình luận
  • khoảng trắng thêm

Việc triển khai tham chiếu JSON5 ( json5gói npm ) cung cấp một JSON5đối tượng có parsestringifycác phương thức có cùng các đối số và ngữ nghĩa như JSONđối tượng tích hợp.


-2

Vì bạn có thể đặt ký hiệu rải rác "Parent.child" và bạn không phải đặt cha mẹ ["con"] cũng hợp lệ và hữu ích, tôi nói cả hai cách đều được chấp nhận về mặt kỹ thuật. Tất cả các trình phân tích cú pháp nên làm cả hai cách tốt. Nếu trình phân tích cú pháp của bạn không cần dấu ngoặc kép trên các phím thì có lẽ tốt hơn là không đặt chúng (tiết kiệm không gian). Thật hợp lý khi gọi chúng là các chuỗi bởi vì đó là những gì chúng là, và vì dấu ngoặc vuông cung cấp cho bạn khả năng sử dụng các giá trị cho các khóa về cơ bản nên không có ý nghĩa hoàn hảo. Trong Json bạn có thể đặt ...

>var keyName = "someKey";
>var obj = {[keyName]:"someValue"};

>obj
Object {someKey: "someValue"}

chỉ tốt mà không có vấn đề gì, nếu bạn cần một giá trị cho khóa và không có trích dẫn nào sẽ không hoạt động, vì vậy nếu không, bạn không thể, vì vậy bạn sẽ không "bạn không cần trích dẫn về khóa". Ngay cả khi nó đúng khi nói rằng chúng là các chuỗi kỹ thuật. Logic và cách sử dụng tranh luận khác. Nó cũng không chính thức xuất Object {"someKey": "someValue"} cho obj trong ví dụ của chúng tôi chạy từ bảng điều khiển của bất kỳ trình duyệt nào.


2
Cả câu trả lời được chấp nhận và RFC định nghĩa JSON đều nói rằng các trích dẫn là bắt buộc.
Keith Thompson

Đó là sự thật, nhưng đáng chú ý là nó không cần thiết. Tôi cho rằng đầu ra Ký hiệu đối tượng JavaScript từ tất cả các bảng điều khiển trình duyệt là sai và chúng tôi nên nói với ai đó để khắc phục điều đó. Có thể những gì bảng điều khiển Trình duyệt xuất ra cho một đối tượng không phải là JSON, vì vậy có thể JSON như định nghĩa cụ thể không cần thiết cũng như không được triển khai theo cách đó ở hầu hết các nơi. Dù sao tôi chỉ muốn làm cho vụ án, đó là nhìn vào sự thật ở một khía cạnh khác. Thực sự có lẽ thông số kỹ thuật nên được thay đổi sau đó, "Khóa trích dẫn" đơn giản là không cần thiết ở bất cứ nơi nào quan trọng với cá nhân tôi. (Nó chỉ không được sử dụng theo cách đó trong thực tế.)
Master James

2
Bạn đang trộn lẫn ba thứ khác nhau: JSON, chữ đối tượng JavaScript và đầu ra bảng điều khiển của công cụ phát triển trình duyệt. Khi bạn nhập objvào bảng điều khiển, trình duyệt sẽ hiển thị một số đại diện có thể đọc được của đối tượng. Nó có thể hiển thị nó dưới dạng một đối tượng theo nghĩa đen (như trong ví dụ của bạn) hoặc nó có thể sử dụng một số đại diện khác, thậm chí là một tương tác. Các đối tượng JavaScript không yêu cầu dấu ngoặc kép quanh tên khóa nếu khóa là định danh hợp lệ và không phải là từ dành riêng. Tuy nhiên, JSON luôn yêu cầu trích dẫn xung quanh các tên chính.
Michael Geary

3
Như các ví dụ khác, thay vì gõ objvào bàn điều khiển, hãy thử JSON.stringify(obj). Bây giờ bạn sẽ thấy một biểu diễn JSON hợp lệ của đối tượng, hoàn thành với tên khóa được trích dẫn. Ngược lại, để xem chuỗi có hợp lệ JSON không, hãy thử JSON.parse(string). Nếu các khóa không được trích dẫn, điều này sẽ ném một ngoại lệ. Chẳng hạn, JSON.parse('{"a":"b"}')sẽ thành công, nhưng JSON.parse('{a:"b"}')sẽ thất bại.
Michael Geary

1
OTOH, việc sử dụng của bạn var obj = {[keyName]:"someValue"};là rất thú vị! Tôi không biết bạn có thể làm điều đó trong một đối tượng JavaScript theo nghĩa đen. Một chút kiểm tra cho thấy đây là một điều mới mẻ trong ES6 - bạn không thể làm điều đó trong ES5.
Michael Geary
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.