Detailed explanation of JSON.parse and JSON.stringify

JSON format, (abbreviated as JavaScript Object Notation), is a text format for data exchange, which is easy to write.
Based on native JavaScript syntax, it can serialize objects, arrays, numbers, strings, Boolean values ​​and null.

In ES5, a JSON object is added, which is specially used to process data in JSON format.
JSON is an object, but has only two methods: parse and  stringify, cannot be used as a constructor, and has no properties.

typeof JSON === 'object'

JSON.parse

JSON.parse() Used to parse JSON strings to get corresponding JavaScript values ​​or objects.

JSON.parse('{}') // {}
JSON.parse('true') // true
JSON.parse('null') // null

JSON.parse syntax

JSON.parse(text[, reviver])
  • text: The string to be parsed into.
    If a number is passed in, it will be converted to decimal number output.
    If a boolean value is passed in, it will be output directly.
    If null is passed in, null is output.
    Values ​​of other types are not supported, otherwise an error will be reported.
  • reviver: Optional, converter, which can be used to modify the original value generated by parsing.

Return value:  JavaScript object/value, object/value corresponding to the given JSON text.

reviver parameter

The reviver function is used to convert and process the parsed JavaScript value, and return the final result after processing.

Conversion process:

  • key The parsed value itself and all the attributes it may contain are called reviver function according to a certain traversal order, and the attribute name and  value are passed in as two parameters  value .
    Traversal order: According to the level, it traverses from the inside to the outside, and finally reaches the top level, which is the parsed value itself.
  • If reviver returns undefined, the object is deleted, and if another value is returned, the value becomes the new value of the current property.
  • When traversing to the top level, because there are no attributes, the parameter key is an empty string '', and the parameter value is the current parsed value.

key For the sum of the two arguments  of the reviver function  value, different data types:

  • Basic value type data (string, number, boolean) and null, as well as empty objects {}and empty arrays []:
    the key is an empty string, and the value is the corresponding parsed value.
    Because it is already the topmost layer and has no other attributes.
  • Object object:
    Both key and value exist, corresponding to the attribute name and value.
    The topmost layer will return a value whose parameter key is empty.
  • Array:
    The key corresponds to the array index, and the value corresponds to the element value.
    The topmost layer will return a value whose parameter key is empty.

Conversion of basic types:

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 objects and arrays:

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:: {}

data processing:

JSON.parse('[1, 2]', function (key, value) {
  if(key === '') {
    return value
  }
  return value + 3
})
// [4, 5]

JSON.parse Traits

When parsing JSON strings, you need to pay attention to some specifications of the JSON format, otherwise it is easy to report errors.
JSON data has strict regulations on the type and format of values. The specific rules are as follows:

  1. This method uses string type JSON format data.
    This method also supports three types of values: number, boolean and null, and converts the corresponding literal value.
    Other types are not supported.
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
  1. Strings must use double quotes, not single quotes.
JSON.parse('"String"')
// 'String'
JSON.parse('\'String\'')
// Uncaught SyntaxError: Unexpected token ' in JSON at position 0
  1. Only decimal strings are supported, but numbers must follow the decimal point.
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
  1. Undefined, Symbol, and BigInt cannot be used, and numbers do not support NaN, Infinity, and -Infinity, and an error will be reported.
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
  1. Composite types can only be: [] and  {} such literals.
    The object constructor cannot be used, because it will be regarded as an execution statement, which is not supported.
    Object and Array cannot be used, nor functions, RegExp objects, Date objects, Error objects, etc.
JSON.parse('[]')
// []
JSON.parse('Object()')
// Uncaught SyntaxError: Unexpected token O in JSON at position 0
  1. Object property names must use double quotes.
JSON.parse('{"key": 1 }')
// {key: 1}
JSON.parse('{key: 1 }')
// Uncaught SyntaxError: Unexpected token k in JSON at position 1
  1. A comma cannot be added after the last member of an array or object.
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
  1. Support for unicode escapes.
JSON.parse('{"\u0066":333}')
// {f: 333}
  1. Some control characters and escape characters are not supported, such as '\n', '\t', etc.
JSON.parse('"\n"')
// Uncaught SyntaxError: Unexpected token 

Other methods of parsing

To convert the json string into a json object (js object value), you can also use other methods, but it is not a safe code.

  const str = '{"name":"json","age":18}'
  const json = JSON.parse(str)
  const json = eval("(" + str + ")")
  const json = (new Function("return " + str))()

JSON.stringify

JSON.stringify() Convert a JavaScript object or value to a JSON-formatted string.

JSON.stringify syntax

JSON.stringify(value[, replacer [, space]])
  • value: The JavaScript object or value that will be serialized into a JSON string.
  • The replacer is optional and is used to handle the value to be serialized.
  • space is optional, specifying a blank string for indentation, used to beautify the output.

Return Value:  A JSON-formatted string representing the given value.

replacer parameter

The replacer parameter can be in the following three situations:

  1. If it is null, undefined or other types, it will be ignored and not processed;
JSON.stringify({key: 'json'}, null, null) // '{"key":"json"}'
JSON.stringify({key: 'json'}, true) // '{"key":"json"}'
  1. If it is an array, only the property names contained in the array will be serialized into the result string;
    only valid for object properties, not valid for arrays.
const obj = {
  json: 'JSON',
  parse: 'PARSE',
  stringify: 'STRINGIFY'
}
JSON.stringify(obj, ['parse', 'stringify'])
// '{"parse":"PARSE","stringify":"STRINGIFY"}'
  1. If it is a function, each attribute of the serialized value will be converted and processed by the function;

Process:

  • The function has two parameters, the attribute name (key) and the attribute value (value), which will be serialized;
  • When calling for the first time, the key is an empty string, and the value is the entire object that needs to be serialized;
  • In the second processing, the result of the first time will be transmitted, and each subsequent processing will receive the result of the previous processing;
  • Later, each attribute name and attribute value will be processed in turn, and returned after completion.
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 type processing:

  • If the basic type string, number, boolean value, null is returned, it will be directly added to the serialized JSON string;
  • If other objects are returned, the properties of the object will be serialized in sequence, and if it is a function, it will not be processed;
  • If returned or undefined, the property will not be output.
  • When serializing an array, if value returns undefined or a function, it will be replaced by null.
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"}'

The following example is the processing when returning an object value:

JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  if (typeof value === 'object') { // 第一次返回整个对象时,类型是object
    return { parse: 'dd' }
  }
  return value
}) 
'{"parse":"dd"}'

space parameter

The space parameter is used to control the spacing in the result string and beautify the output. There are three types of values ​​that can be entered:

  • If it is a number, when serializing, each level is indented with more spaces corresponding to the number value than the previous level, ranging from 1 to 10, that is, a minimum of 1 and a maximum of 10 spaces;
  • If it is a string, the string will be added in front of each line during serialization, and the string will be indented more at each level than the previous level, up to a character, and the string will be intercepted if it exceeds;
  • If it is null, undefined or other types, it will be ignored and not processed.
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 Trait

  1. Basic type value strings, numbers, and Boolean values, as well as String, Boolean, and Number object values, will be converted into primitive value strings for output.
JSON.stringify(333) // '333'
JSON.stringify(true) // 'true'
JSON.stringify(new String('333')) //'"333"'
JSON.stringify(Boolean(true)) // 'true'
  1. The basic type of string, the conversion result will be enclosed in double quotes.
    Because when reverting, the double quotes let JavaScript know that it is a string, not a variable.
JSON.stringify('json') === 'json' // false
JSON.stringify('json') === '"json"' // true
  1. undefined, functions, symbols, and XML objects:
  • When it appears in an Object object, it will be ignored;
  • When it appears in an array, it will be serialized as null;
  • When present alone, undefined will be returned.
JSON.stringify(Symbol()) // undefined
JSON.stringify([Symbol(), Math.abs, undefined]) // '[null,null,null]'
JSON.stringify({ [Symbol()]: Math.abs, key: undefined }) // '{}'
  1. Values ​​such as NaN, Infinity, and -Infinity, as well as null, will be serialized as null.
JSON.stringify(null) // 'null'
JSON.stringify(NaN) // 'null'
  1. Object objects, and Map/Set/WeakMap/WeakSetother composite type objects, will ignore the non-traversable properties of the object when serializing.
const obj = {}
Object.defineProperties(obj, {
  'json': { value: 'JSON', enumerable: true },
  'stringify': { value: 'STRINGIFY', enumerable: false }
})
JSON.stringify(obj)
// '{"json":"JSON"}'
  1. Attributes with symbol as the attribute name will be ignored.
JSON.stringify({[Symbol()]: 333}) // '{}'
  1. Except for arrays, the properties of other objects may be out of order when serialized.
const a = { '1': 911, 'r': 822, '11': 9922}
JSON.stringify(a)
// '{"1":911,"11":9922,"r":822}'
  1. If the converted object defines  toJSON() a method, the return value of the method is the serialized result of the converted object.
    The process ignores other properties.
const a = { key: 'json' }
a.toJSON = () => 'JSON'
JSON.stringify(a)
// '"JSON"'
  1. Both RegExp objects and Error objects will be serialized as empty object strings.
JSON.stringify(/\d/) // "{}"
JSON.stringify(new Error())  // "{}"

To serialize the corresponding object, you need to implement the toJSON method.

RegExp.prototype.toJSON = RegExp.prototype.toString
JSON.stringify(/\d/) // '"/\\\\d/"'
  1. The Date object has defined toJSON() and converts it to a string string, so it can be serialized.
    Same Date.toISOString().
JSON.stringify(new Date())
// '"2021-12-31T02:24:05.477Z"'
  1. Objects with circular references execute this method and an error will be thrown.
    Objects refer to each other, forming an infinite loop.
const a = {}
a.key = a
JSON.stringify(a)
// Uncaught TypeError: Converting circular structure to JSON
  1. Converting a value of type BigInt will throw a TypeError error.
    BigInt values ​​cannot be JSON serialized
JSON.stringify(12n)
// Uncaught TypeError: Do not know how to serialize a BigInt
  1. Better support for unicode escape characters
const a = {'\u0066': 333}
JSON.stringify(a)
// '{"f":333}'

Guess you like

Origin blog.csdn.net/jh035/article/details/128128164