{ "first": "Jane", "last": "Porter", "married": true, "born": 1890, "friends": [ "Tarzan", "Cheeta" ] }JSON uses the following constructs from JavaScript expressions:
I discovered JSON. I do not claim to have invented JSON, because it already existed in nature. What I did was I found it, I named it, I described how it was useful. I don't claim to be the first person to have discovered it; I know that there are other people who discovered it at least a year before I did. The earliest occurrence I've found was, there was someone at Netscape who was using JavaScript array literals for doing data communication as early as 1996, which was at least five years before I stumbled onto the idea.
The JSON grammar on a business card. [source] |
- object
- { }
- { members }
- members
- pair
- pair , members
- pair
- string : value
- array
- [ ]
- [ elements ]
- elements
- value
- value , elements
- value
- object
- array
- string
- number
- true
- false
- null
- string
- ""
- " chars "
- chars
- char
- char chars
- char
- <any Unicode character except " or \ or control characters>
- \\ \" \/ \b \f \n \r \t
- \u <four hex digits>
- number
- int
- int frac
- int exp
- int frac exp
- int
- digit
- digit1-9 digits
- - digit
- - digit1-9 digits
- frac
- . digits
- exp
- e digits
- digits
- digit
- digit digits
- e
- e e+ e-
- E E+ E-
function (key, value)The parameters are:
function nodeVisitor(key, value) { console.log( JSON.stringify(this) // parent +"#"+JSON.stringify(key) +"#"+JSON.stringify(value)); return value; // don't change }The above function only uses JSON.stringify(), because it is a good way of displaying JavaScript values. It is used below to examine how iteration works.
Order and kind of nodes visited – stringify. The special root node comes first, in a prefix iteration (parent before children). The last values are the results of the function calls.
> JSON.stringify(["a","b"], nodeVisitor) {"":["a","b"]}#""#["a","b"] ["a","b"]#"0"#"a" ["a","b"]#"1"#"b" '["a","b"]' > JSON.stringify({"a":1, "b":2}, nodeVisitor) {"":{"a":1,"b":2}}#""#{"a":1,"b":2} {"a":1,"b":2}#"a"#1 {"a":1,"b":2}#"b"#2 '{"a":1,"b":2}' > JSON.stringify("abc", nodeVisitor) {"":"abc"}#""#"abc" '"abc"'Order and kind of nodes visited – parse. The leaves come first, in a postfix iteration (children before parent). The last values are the results of the function calls.
> JSON.parse('["a","b"]', nodeVisitor) ["a","b"]#"0"#"a" ["a","b"]#"1"#"b" {"":["a","b"]}#""#["a","b"] [ 'a', 'b' ]> JSON.parse('{"a":1, "b":2}', nodeVisitor) {"a":1,"b":2}#"a"#1 {"a":1,"b":2}#"b"#2 {"":{"a":1,"b":2}}#""#{"a":1,"b":2} { a: 1, b: 2 }
> JSON.parse('"hello"', nodeVisitor) {"":"hello"}#""#"hello" 'hello'
function replacer(key, value) { if (typeof value === "number") { value = 2 * value; } return value; }Interaction:
> JSON.stringify({ a: 5, b: [ 2, 8 ] }, replacer) '{"a":10,"b":[4,16]}'
JSON.stringify({foo: 1, bar: {foo: 1, bar: 1}}, ["bar"])returns
'{"bar":{"bar":1}}'
> console.log(JSON.stringify({a: 0, b: ["\n"]})) {"a":0,"b":["\n"]}With it, newlines are inserted and each level of nesting via arrays and objects increases indentation. There are two ways to specify how to indent:
> console.log(JSON.stringify({a: 0, b: ["\n"]}, null, 2)) { "a": 0, "b": [ "\n" ] }
> console.log(JSON.stringify({a: 0, b: ["\n"]}, null, "|–")) { |–"a": 0, |–"b": [ |–|–"\n" |–] }
> JSON.stringify({ toJSON: function() { return "Cool" } }) '"Cool"'Dates already have a toJSON method which produces an ISO 8601 date string:
> JSON.stringify(new Date("2011-07-29")) '"2011-07-28T22:00:00.000Z"'The full signature of a toJSON method is as follows.
function(key)The key parameter allows you to stringify differently, depending on context. It is always a string and denotes where in the parent object your object was found:
var obj = { toJSON: function(key) { console.log(key) } } JSON.stringify({ foo: obj, bar: [ obj ]});Output:
foo 0
> JSON.parse("'String'") // illegal single quotes SyntaxError: Unexpected token ILLEGAL > JSON.parse('"String"') 'String' > JSON.parse("123") 123 > JSON.parse("[1, 2, 3]") [ 1, 2, 3 ] > JSON.parse('{ "hello": 123, "world": 456 }') { hello: 123, world: 456 }The optional parameter reviver is a node visitor and can be used to transform the parsed data. Example: translating date strings to date objects.
function dateReviver(key, value) { if (typeof value === "string") { var x = Date.parse(value); if (!isNaN(x)) { // valid date string? return new Date(x); } } return value; }Note: You can also use a regular expression to check whether a given string is a date string.
> JSON.parse( '{ "name": "John", "birth": "2011-07-28T22:00:00.000Z" }', dateReviver) { name: 'John', birth: Thu, 28 Jul 2011 22:00:00 GMT }