JSON格式,(简写JavaScript Object Notation),是一种用于数据交换的文本格式,书写简单。
基于JavaScript原生语法,能够序列化对象、数组、数值、字符串、布尔值和 null。
在ES5中,增加了一个JSON对象,专门用来处理JSON格式的数据。
JSON是一个对象,但只有两个方法:parse
和 stringify
,不能作为构造函数,也无属性。
typeof JSON === 'object'
JSON.parse()
用来解析JSON字符串,得到对应的JavaScript值或对象。
- JSON.parse('{}') // {}
- JSON.parse('true') // true
- JSON.parse('null') // null
JSON.parse(text[, reviver])
返回值: JavaScript对象/值, 对应给定JSON文本的对象/值。
reviver函数,用于转换处理解析到的JavaScript值,处理完后返回最终的结果。
转换过程:
key
和 value
传入。''
,参数value则是当前解析值。对于reviver函数的两个参数 key
和 value
,不同的数据类型:
{}
和空数组[]
:基本类型的转换:
- JSON.parse('5', function (key, value) {
- console.log(`key:${key}, value:${value}`)
- })
- // key:, value:5
- JSON.parse('null', function (key, value) {
- console.log(`key:${key}, value:${value}`)
- })
- // key:, value:null
- JSON.parse('{}', function (key, value) {
- console.log(`key:${key}, value:`, value)
- })
- // key:, value:{}
Object对象和数组:
- JSON.parse('[1, 2]', function (key, value) {
- console.log(`key:${key}, value:`, value)
- })
- // key:0, value: 1
- // key:1, value: 2
- // key:, value: (2) [empty × 2]
-
- JSON.parse('{ "user": "张三", "info": { "age": 25, "sex": 1 } }', function (key, value) {
- console.log(`key:${key}, value::`, value)
- })
- // key:user, value:: 张三
- // key:age, value:: 25
- // key:sex, value:: 1
- // key:info, value:: {}
- // key:, value:: {}
数据处理:
- JSON.parse('[1, 2]', function (key, value) {
- if(key === '') {
- return value
- }
- return value + 3
- })
- // [4, 5]
在解析JSON字符串的时候,需要注意到JSON格式的一些规范,不然就容易报错。
JSON数据对值的类型和格式,都有严格的规定,具体的规则如下:
- JSON.parse('"中国"')
- // '中国'
- JSON.parse(null) // null
- JSON.parse(111.) // 111
- JSON.parse(0x12) // 18
- JSON.parse(true) // true
- JSON.parse([])
- // Uncaught SyntaxError: Unexpected end of JSON input
- JSON.parse('"String"')
- // 'String'
- JSON.parse('\'String\'')
- // Uncaught SyntaxError: Unexpected token ' in JSON at position 0
- JSON.parse('111') // 111
- JSON.parse('0x12')
- // Uncaught SyntaxError: Unexpected token x in JSON at position 1
- JSON.parse('111.232') // 111.232
- JSON.parse('111.')
- // Uncaught SyntaxError: Unexpected end of JSON input
- JSON.parse(undefined)
- // Uncaught SyntaxError: Unexpected token u in JSON at position 0
- JSON.parse(Symbol())
- // Uncaught TypeError: Cannot convert a Symbol value to a string
- JSON.parse('12n')
- // Uncaught SyntaxError: Unexpected token n in JSON at position 2
[]
和 {}
这样的字面量。- JSON.parse('[]')
- // []
- JSON.parse('Object()')
- // Uncaught SyntaxError: Unexpected token O in JSON at position 0
- JSON.parse('{"key": 1 }')
- // {key: 1}
- JSON.parse('{key: 1 }')
- // Uncaught SyntaxError: Unexpected token k in JSON at position 1
- JSON.parse('[1, 2, 3, 4, ]')
- // VM2771:1 Uncaught SyntaxError: Unexpected token ] in JSON at position 13
- JSON.parse('{"key" : 1, }')
- // VM2779:1 Uncaught SyntaxError: Unexpected token } in JSON at position 12
- JSON.parse('{"\u0066":333}')
- // {f: 333}
- JSON.parse('"\n"')
- // Uncaught SyntaxError: Unexpected token
将json字符串转成json对象(js对象值),还可以使用其他方法,但是非安全代码。
- const str = '{"name":"json","age":18}'
- const json = JSON.parse(str)
- const json = eval("(" + str + ")")
- const json = (new Function("return " + str))()
JSON.stringify()
将一个JavaScript对象或值转换为JSON格式字符串。
JSON.stringify(value[, replacer [, space]])
返回值: 一个表示给定值的JSON格式字符串。
replacer 参数可以以下三种情况:
- JSON.stringify({key: 'json'}, null, null) // '{"key":"json"}'
- JSON.stringify({key: 'json'}, true) // '{"key":"json"}'
- const obj = {
- json: 'JSON',
- parse: 'PARSE',
- stringify: 'STRINGIFY'
- }
- JSON.stringify(obj, ['parse', 'stringify'])
- // '{"parse":"PARSE","stringify":"STRINGIFY"}'
处理过程:
- JSON.stringify({ json: 1, stringify: { val: 'rr'} }, (key, value) => {
- console.log(`key:${key},value:`, value)
- return value
- })
- // key:,value: {json: 1, stringify: {…}}
- // key:json,value: 1
- // key:stringify,value: {val: 'rr'}
- // key:val,value: rr
- // '{"json":1,"stringify":{"val":"rr"}}'
value的类型处理:
- JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
- if (typeof value === 'number') {
- return 'ss'
- }
- return value
- })
- // '{"json":"ss","stringify":"rr"}'
-
- JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
- if (typeof value === 'number') {
- value = undefined
- }
- return value
- })
- // '{"stringify":"rr"}'
下面示例,是返回对象值时的处理:
- JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
- if (typeof value === 'object') { // 第一次返回整个对象时,类型是object
- return { parse: 'dd' }
- }
- return value
- })
- '{"parse":"dd"}'
space 参数用来控制结果字符串里面的间距,美化输出。可以输入的值有以下三种情况:
- JSON.stringify({key: 'json'}, null, 2)
- // '{\n "key": "json"\n}'
- JSON.stringify({key: 'json', list: { str: 'str' } }, null, '|-')
- // '{\n|-"key": "json",\n|-"list": {\n|-|-"str": "str"\n|-}\n}'
- JSON.stringify({key: 'json'}, null, null)
- // '{"key":"json"}'
- JSON.stringify(333) // '333'
- JSON.stringify(true) // 'true'
- JSON.stringify(new String('333')) //'"333"'
- JSON.stringify(Boolean(true)) // 'true'
- JSON.stringify('json') === 'json' // false
- JSON.stringify('json') === '"json"' // true
- JSON.stringify(Symbol()) // undefined
- JSON.stringify([Symbol(), Math.abs, undefined]) // '[null,null,null]'
- JSON.stringify({ [Symbol()]: Math.abs, key: undefined }) // '{}'
- JSON.stringify(null) // 'null'
- JSON.stringify(NaN) // 'null'
Map/Set/WeakMap/WeakSet
等复合类型对象,序列化时会忽略对象的不可遍历属性。- const obj = {}
- Object.defineProperties(obj, {
- 'json': { value: 'JSON', enumerable: true },
- 'stringify': { value: 'STRINGIFY', enumerable: false }
- })
- JSON.stringify(obj)
- // '{"json":"JSON"}'
JSON.stringify({[Symbol()]: 333}) // '{}'
- const a = { '1': 911, 'r': 822, '11': 9922}
- JSON.stringify(a)
- // '{"1":911,"11":9922,"r":822}'
toJSON()
方法,则该方法的返回值就是转换对象的序列化结果。- const a = { key: 'json' }
- a.toJSON = () => 'JSON'
- JSON.stringify(a)
- // '"JSON"'
- JSON.stringify(/\d/) // "{}"
- JSON.stringify(new Error()) // "{}"
想要序列化相应对象,需要设置实现toJSON方法才行。
- RegExp.prototype.toJSON = RegExp.prototype.toString
- JSON.stringify(/\d/) // '"/\\\\d/"'
Date.toISOString()
。- JSON.stringify(new Date())
- // '"2021-12-31T02:24:05.477Z"'
- const a = {}
- a.key = a
- JSON.stringify(a)
- // Uncaught TypeError: Converting circular structure to JSON
- JSON.stringify(12n)
- // Uncaught TypeError: Do not know how to serialize a BigInt
- const a = {'\u0066': 333}
- JSON.stringify(a)
- // '{"f":333}'