JSON Serialization

JavaScript supports JSON (JavaScript Object Notation) serialization and deserialization with JSON.stringify() and JSON.parse() functions.

let o = {s: '', n: 0, a: [true, false, null]};
let s = JSON.stringify(o); // '{"s":"","n":0,"a":[true,false,null]}'
let copy = JSON.parse(s);

If the second optional argument to JSON.stringify() is an array of strings (or numbers which are converted to strings), these are used as the names of object properties to serialize. Any property whose name is not in the array will be omitted from the serialization.

let address = {city: 'Moscow', country: 'Russia', planet: 'Earth'};
s = JSON.stringify(address, ['city', 'country']);
s; // => '{"city":"Moscow","country":"Russia"}'

If the second optional argument to JSON.stringify() is a function, it is invoked for each value to be serialized. The return value of the function is serialized in place of the original value. If the return value is undefined, then that value is omitted from the serialization.

let obj = {s: '', n: 0, r: /js/};
s = JSON.stringify(obj, (k,v) => v instanceof RegExp ? undefined: v);
s; // => '{"s":"","n":0}'

The third optional argument to JSON.stringify() specifies the indentation used to produce a human-readable string on multiple indented lines. If a number is provided, then that number of spaces is used for each indentation level. If a string of whitespace (such as \t) is provided, then it will be used for each level of indentation.

let person = {name: 'Roman', age: 28};
JSON.stringify(person, null, 2); // => '{\n  "name": "Roman",\n  "age": 28\n}'

The second optional argument to JSON.parse() is a reviver function that is invoked once for each primitive value parsed from the input string. If the function returns undefined, then the named property will be deleted.

let text = '{"_s": "", "n": 0, "date": "2024-05-17T04:22:43.113Z"}';
let data = JSON.parse(text, (key, value) => {
  if (key[0] === '_') return undefined;

  const date_pattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
  if (typeof value === 'string' && date_pattern.test(value)) {
    return new Date(value);
  }

  return value;
});