Title: JavaScript: The Good Parts Part Eleven: JSON
1JavaScript The Good PartsPart Eleven JSON
- Douglas Crockford
- douglas_at_crockford.com
2JSONThe x in Ajax
- Douglas Crockford
- Yahoo! Inc.
3The Yoda of lambda programming and JavaScript
4JSON is not even XML!Who did this travesty?
Lets find a tree and string them up. Now.
5any damn fool could produce a better data format
than XML
6I Discovered JSON
- I do not claim to have invented JSON. It already
existed in nature. - I do not claim to have been the first to discover
it. - I gave it a name, a specification, and a little
website. - The rest happened by itself.
7JSON News
8Native JSON support in ECMAScript, Fifth Edition.
- It is available now in IE8.
- http//www.JSON.org/json2.js
9JSON.parse(text, reviver)
- text is a JSON text to be parsed.
- reviver is an optional function that will be
called for each of the values in the new object,
giving an opportunity to modify the result. - function reviver(key, value)
- return new_value
10Example
- If a property name contains date, convert the
value into a Date object. - function my_reviver(key, value)
- return key.indexOf('date') gt 0 ?
new Date(value) value -
- my_object JSON.parse(my_text, my_reviver)
11Recommended Practice
- Design your constructor functions to take a
single parameter which is the value produced by
JSON.parse. - The constructor can attach structure and behavior
to the data.
12JSON.stringify(value, replacer, space)
- value is a JavaScript value to be stringified.
- replacer is an optional function that will be
called for each of the values, giving an
opportunity to modify the result. - space is an optional pretty printing parameter.
13toJSON
- An object may have or inherit a toJSON method
that will be called by JSON.stringify. - It allows the object to substitute another value.
- It does not return the serialization of the
value. - It returns the value to be serialized.
- function toJSON(key)
- return new_value
14replacer
- The replacer function is passed the key and the
value produced by toJSON. - this is bound to the object that holds the key,
so thiskey is the original value. - function replacer(key, value)
- return new_value
15Example
- If a property name contains date, convert the
value into string. - function my_reviver(key, value)
- return key.indexOf('date') gt 0 ?
value.toISOString() value -
- my_object JSON.stringify(my_text, my_reviver)
16replacer Whitelist
- If replacer is an array of strings, those strings
will be used to select the properties that will
be stringified.
17space
- The optional space parameter can be the number of
spaces in each level in indentation, or a string
(such as '\t') that will be accumulated for each
level of indentation. - This can produce strings that are easier to read.
18-
- "value" "",
- "arity" "binary",
- "first"
- "value" "make_parse",
- "arity" "name"
- ,
- "second"
- "value" "function",
- "arity" "function",
- "first" ,
- "second"
-
- "value" "",
19JSON Databases
- CouchDB is a distributed, fault-tolerant and
schema-free document-oriented database accessible
via a RESTful HTTP/JSON API. - Also, Persevere, DBSlayer, StrokeDB, SpringDB.
20What about XML?
21XML Form
- ltrecipe name"bread" prep_time"5 mins"
cook_time"3 hours"gt - lttitlegtBasic breadlt/titlegt
- ltingredient amount"8" unit"dL"gtFlourlt/ingredi
entgt - ltingredient amount"10" unit"grams"gtYeastlt/ing
redientgt - ltingredient amount"4" unit"dL"
state"warm"gtWaterlt/ingredientgt - ltingredient amount"1" unit"teaspoon"gtSaltlt/in
gredientgt - ltinstructionsgt
- ltstepgtMix all ingredients together.lt/stepgt
- ltstepgtKnead thoroughly.lt/stepgt
- ltstepgtCover with a cloth, and leave for one
hour in warm room.lt/stepgt - ltstepgtKnead again.lt/stepgt
- ltstepgtPlace in a bread baking tin.lt/stepgt
- ltstepgtCover with a cloth, and leave for one
hour in warm room.lt/stepgt - ltstepgtBake in the oven at 180(degrees)C for
30 minutes.lt/stepgt - lt/instructionsgt
- lt/recipegt
22Data Form
- "recipe"
- "name" "bread", "title" "Basic bread"
- "cook_time" "3 hours", "prep_time" "5
mins", - "ingredient"
- "amount" 8, "content" "Flour", "unit"
"dL", - "amount" 10, "content" "Yeast",
"unit" "grams", - "amount" 4, "content" "Water",
"state" "warm", "unit" "dL", - "amount" 1, "content" "Salt", "unit"
"teaspoon" - ,
- "instructions" "step"
- "Mix all ingredients together.",
- "Knead thoroughly.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Knead again.",
- "Place in a bread baking tin.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Bake in the oven at 180(degrees)C for 30
minutes." -
23Data Form
- "recipe"
- "name" "bread", "title" "Basic bread"
- "cook_time" "3 hours", "prep_time" "5
mins", - "ingredient"
- "amount" 8, "content" "Flour", "unit"
"dL", - "amount" 10, "content" "Yeast",
"unit" "grams", - "amount" 4, "content" "Water",
"state" "warm", "unit" "dL", - "amount" 1, "content" "Salt", "unit"
"teaspoon" - ,
- "instructions" "step"
- "Mix all ingredients together.",
- "Knead thoroughly.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Knead again.",
- "Place in a bread baking tin.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Bake in the oven at 180(degrees)C for 30
minutes." -
24Data Form
- "recipe"
- "name" "bread", "title" "Basic bread"
- "cook_time" "3 hours", "prep_time" "5
mins", - "ingredient"
- "amount" 8, "content" "Flour", "unit"
"dL", - "amount" 10, "content" "Yeast",
"unit" "grams", - "amount" 4, "content" "Water",
"state" "warm", "unit" "dL", - "amount" 1, "content" "Salt", "unit"
"teaspoon" - ,
- "instructions" "step"
- "Mix all ingredients together.",
- "Knead thoroughly.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Knead again.",
- "Place in a bread baking tin.",
- "Cover with a cloth, and leave for one
hour in warm room.", - "Bake in the oven at 180(degrees)C for 30
minutes." -
my_object.recipe.instructions.step0 my_object.
instructions0
25Data Form is more effective than XML at
representing data.
- It is not effective at representing documents and
semidocuments.
26Array Form
- "recipe", "cook_time" "3 hours", "name"
"bread", "prep_time" "5 mins", - "title", "Basic bread",
- "ingredient", "amount" 8, "unit" "dL",
"Flour", - "ingredient", "amount" 10, "unit"
"grams", "Yeast", - "ingredient", "amount" 4, "state" "warm",
"unit" "dL", "Water", - "ingredient", "amount" 1, "unit"
"teaspoon", "Salt", - "instructions",
- "step", "Mix all ingredients
together.", - "step", "Knead thoroughly.",
- "step", "Cover with a cloth, and leave
for one hour in warm room.", - "step", "Knead again.",
- "step", "Place in a bread baking tin.",
- "step", "Cover with a cloth, and leave
for one hour in warm room.", - "step","Bake in the oven at
180(degrees)C for 30 minutes." -
27Object Form
- "tagName" "recipe", "cook_time" "3 hours",
"name" "bread", "childNodes" - "tagName" "title", "childNodes" "Basic
bread", - "amount" "8", "unit" "dL", "tagName"
"ingredient", "childNodes" "Flour", - "amount" "10", "unit" "grams", "tagName"
"ingredient", "childNodes" "Yeast", - "amount" "4", "unit" "dL", "tagName"
"ingredient", "state" "warm", "childNodes"
"Water", - "amount" "1", "unit" "teaspoon",
"tagName" "ingredient", "childNodes" "Salt",
- "tagName" "instructions", "childNodes"
- "tagName" "step", "childNodes" "Mix
all ingredients together.", - "tagName" "step", "childNodes" "Knead
thoroughly.", - "tagName" "step", "childNodes" "Cover
with a cloth, and leave for one hour in warm
room.", - "tagName" "step", "childNodes" "Knead
again.", - "tagName" "step", "childNodes" "Place
in a bread baking tin.", - "tagName" "step", "childNodes" "Cover
with a cloth, and leave for one hour in warm
room.", - "tagName" "step", "childNodes" "Bake
in the oven at 180(degrees)C for 30 minutes." - , "prep_time" "5 mins"
-
28XML To Three JSON Forms
- Data Form is most compact.
- Data Form is conveniently manipulated by
programs. - Data Form loses document structure.
- The Array and Object forms retain document
structure (JSONML). - Array Form is more compact than Object Form.
- Object Form conventions match DOM.
29JSON.java Reference Implementation
30Where did the idea come from that data should be
represented by a document format?
31RUNOFF
- .SK 1
- Text processing and word processing systems
- typically require additional information to
- be interspersed among the natural text of
- the document being processed. This added
- information, called "markup", serves two
- purposes
- .TB 4
- .OF 4
- .SK 1
- 1.Separating the logical elements of the
- document and
- .OF 4
- .SK 1
- 2.Specifying the processing functions to be
- performed on those elements.
- .OF 0
- .SK 1
32GML
- h1.Chapter 1 Introduction
- p.GML supported hierarchical containers,
such as - ol
- li.Ordered lists (like this one),
- li.Unordered lists, and
- li.Definition lists
- eol.
- as well as simple structures.
- p.Markup minimization (later generalized and
- formalized in SGML),
- allowed the end-tags to be omitted for the
"h1" - and "p" elements.
33 34Scribe
- _at_Quote(Any damn fool)
- ( )
- lt gt " " ' '
- _at_Begin(Quote)
- Any damn fool
- _at_End(Quote)
35Scribe
- _at_techreport(PUB, key"Tesler", author"Tesler,
Larry", title"PUB The Document Compiler",
year1972, number"ON-72", month"Sep",
institution"Stanford University Artificial
Intelligence Project")_at_book(Volume3,
key"Knuth", - author"Knuth, Donald E.", title"Sorting and
Searching", publisher"Addison-Wesley",year1973,
volume3, - series"The Art of Computer Programming",
address"Reading, Mass.")
36Languages
- Arabic
- Bulgarian
- Chinese
- Czech
- Dutch
- French
- German
- Greek
- Hebrew
- Hungarian
- Indonesian
- Italian
- Japanese
- Korean
- Persian
- Polish
- Portuguese
- Russian
- Slovenian
- Spanish
- Turkish
- Vietnamese
37Languages
- ActionScript
- C / C
- C
- Cold Fusion
- Delphi
- E
- Erlang
- Haskell
- Java
- Lisp
- Lua
- Perl
- Objective-C
- Objective CAML
- PHP
- Prolog
- Python
- Rebol
- Ruby
- Scheme
- Squeak
- TCL
38Versionless
- JSON has no version number.
- No revisions to the JSON grammar are anticipated.
- JSON is very stable.
- Stability is more valuable than any feature we
could add.
39Supersets
- YAML is a superset of JSON.
- A YAML decoder is a JSON decoder.
- JavaScript is a superset of JSON.
- A JavaScript compiler is a JSON decoder.
- New programming languages based on JSON.
40JSONT
- var rules
- self
- 'ltsvggtltclosed stroke"color"
points"points" /gtlt/svggt', - closed function (x) return x ? 'polygon'
'polyline', - 'points' ' '
-
- var data
- "color" "blue",
- "closed" true,
- "points" 10,10, 20,10, 20,20, 10,20
-
- jsonT(data, rules)
- ltsvggtltpolygon stroke"blue"
- points"10 10 20 10 20 20 10 20 " /gtlt/svggt
41http//goessner.net/articles/jsont/
- function jsonT(self, rules)
- var T
- output false,
- init function ()
- for (var rule in rules) if
(rule.substr(0,4) ! "self") rules"self."
rule rulesrule - return this
- ,
- apply function(expr)
- var trf function (s)
- return s.replace(/(A-Za-z0-9_\\
.\\\'_at_\(\))/g, function (0, 1) - return T.processArg(1,
expr) - )
- , x expr.replace(/\0-9\/g,
""), res - if (x in rules)
- if (typeof(rulesx) "string")
res trf(rulesx) - else if (typeof(rulesx)
"function") res trf(rulesx(eval(expr)).toStrin
g()) - else res T.eval(expr)
- return res
- ,
42Don't wrap JSON text in comments
- Intended to close a browser hole.
- / jsontext /
- May open a new hole.
- "/ evil() /"
- Security is not obtained by tricks.
- Never put data on the wire unless you intend that
it be delivered. - Do not rely on Same Origin Policy.
43www.JSON.org