JavaScript & Hardware - April 2016 JavaScript Shanghai Meetup
JavaScript
-
Upload
sampetruda -
Category
Documents
-
view
1.742 -
download
0
Transcript of JavaScript
JSONThe x in Ajax
Douglas CrockfordYahoo! Inc.
The Yoda of lambda programming and
JavaScript
Brendan Eich, 2006-07-31
[JSON is] not even XML!Who did this travesty?
Let’s find a tree and string them up. Now.
Dave Winer, 2006-12-20
any damn fool could produce a better data
format than XML
James Clark, 2007-04-06
I 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.
JSON News
Native JSON support in ECMAScript, Fifth Edition.
It is available now in IE8.
http://www.JSON.org/json2.js
JSON.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;}
Example
• If a property name contains date, convert the value into a Date object.
function my_reviver(key, value) {
return key.indexOf('date') >= 0 ? new Date(value) : value;
}
my_object = JSON.parse(my_text, my_reviver);
Recommended 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.
JSON.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.
toJSON
• 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;}
replacer
• The replacer function is passed the key and the value produced by toJSON.
• this is bound to the object that holds the key, so this[key] is the original value.
function replacer(key, value) { return new_value;}
Example
• If a property name contains date, convert the value into string.
function my_reviver(key, value) {
return key.indexOf('date') >= 0 ? value.toISOString() : value;
}
my_object = JSON.stringify(my_text, my_reviver);
replacer Whitelist
• If replacer is an array of strings, those strings will be used to select the properties that will be stringified.
space
• 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.
{ "value": "=", "arity": "binary", "first": { "value": "make_parse", "arity": "name" }, "second": { "value": "function", "arity": "function", "first": [], "second": [ { "value": "=",
JSON 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.
What about XML?
XML Form<recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="8" unit="dL">Flour</ingredient> <ingredient amount="10" unit="grams">Yeast</ingredient> <ingredient amount="4" unit="dL"
state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together.</step> <step>Knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm
room.</step> <step>Knead again.</step> <step>Place in a bread baking tin.</step> <step>Cover with a cloth, and leave for one hour in warm
room.</step> <step>Bake in the oven at 180(degrees)C for 30 minutes.</step> </instructions> </recipe>
Data 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." ]}}}
Data 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." ]}}}
Data 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.step[0]
my_object.instructions[0]
Data Form is more effective than XML at representing
data.It is not effective at
representing documents and semidocuments.
Array 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."] ]]
Object 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"}
XML 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.
JSON.java Reference Implementation
http://www.JSON.org/java/
Where did the idea come from that data should be
represented by a document format?
RUNOFF.SK 1Text processing and word processing systemstypically require additional information tobe interspersed among the natural text ofthe document being processed. This addedinformation, called "markup", serves twopurposes:.TB 4.OF 4.SK 11.#Separating the logical elements of thedocument; and.OF 4.SK 12.#Specifying the processing functions to beperformed on those elements..OF 0.SK 1
GML :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.
:eol.
::ol.
</ol>
Scribe
@Quote(Any damn fool)
( ) [ ] { } < > " " ' '
@Begin(Quote) Any damn fool@End(Quote)
Scribe
@techreport(PUB, key="Tesler", author="Tesler, Larry", title="PUB: The Document Compiler", year=1972, number="ON-72", month="Sep", institution="Stanford University Artificial Intelligence Project")
@book(Volume3, key="Knuth", author="Knuth, Donald E.", title="Sorting and Searching", publisher="Addison-Wesley",year=1973, volume=3,
series="The Art of Computer Programming", address="Reading, Mass.")
Languages
• Arabic • Bulgarian • Chinese • Czech • Dutch• French • German • Greek • Hebrew • Hungarian• Indonesian
• Italian• Japanese • Korean • Persian • Polish • Portuguese • Russian • Slovenian • Spanish • Turkish • Vietnamese
Languages
• 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
Versionless
• 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.
Supersets
• 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.
JSONTvar rules = {
self: '<svg><{closed} stroke="{color}" points="{points}" /></svg>',
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)
<svg><polygon stroke="blue" points="10 10 20 10 20 20 10 20 " /></svg>
http://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] = rules[rule]; return this; }, apply: function(expr) { var trf = function (s) { return s.replace(/{([A-Za-z0-9_\$\.\[\]\'@\(\)]+)}/g, function ($0, $1){ return T.processArg($1, expr); }) }, x = expr.replace(/\[[0-9]+\]/g, "[*]"), res; if (x in rules) { if (typeof(rules[x]) == "string") res = trf(rules[x]); else if (typeof(rules[x]) == "function") res = trf(rules[x](eval(expr)).toString()); } else res = T.eval(expr); return res; }, processArg: function (arg, parentExpr) { var expand = function (a, e) { return (e = a.replace(/^\$/,e)).substr(0, 4) != "self" ? ("self." + e) : e; }, res = ""; T.output = true; if (arg.charAt(0) == "@") res = eval(arg.replace(/@([A-za-z0-9_]+)\(([A-Za-z0-9_\$\.\[\]\']+)\)/, function($0, $1, $2){ return "rules['self." + $1 + "'](" + expand($2,parentExpr) + ")"; })); else if (arg != "$") res = T.apply(expand(arg, parentExpr)); else res = T.eval(parentExpr); T.output = false; return res; }, eval: function (expr) { var v = eval(expr), res = ""; if (typeof(v) != "undefined") { if (v instanceof Array) { for (var i = 0; i < v.length; i++) if (typeof(v[i]) != "undefined") res += T.apply(expr + "[" + i + "]"); } else if (typeof(v) == "object") { for (var m in v) if (typeof(v[m]) != "undefined") res += T.apply(expr+"."+m); } else if (T.output) res += v; } return res; } }; return T.init().apply("self");}
Don'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.
www.JSON.org