preface

Json.stringify can be used with json.parse for deep copy of objects, as well as string to object conversion, but there are many problems. Here is a simple record for future reference.

Grammatical features

Json.stringify is used to convert JavaScript strings or values into objects.

Undefined, function, Symbol

As an object property value

Undefined, function, or Symbol are ignored during serialization, in other words, lost.

const object = {
  foo: undefined.bar: function () {
    console.log(this)},baz: Symbol('baz'),
  id: 1
}
JSON.stringify(object) // {"id":1}
Copy the code

As an array element

As an array element, is serialized to NULL.

const array = [undefined.function () {},Symbol('foo'), 'bar']
JSON.stringify(array) // [null,null,null,"bar"]
Copy the code

Separate serialization

Serialized separately, undefined is returned.

JSON.stringify(undefined) // undefined
JSON.stringify(function () {})// undefined
JSON.stringify(Symbol('foo')) // undefined
Copy the code

Null, Infinity, NaN

Values in NaN and Infinity formats or null are converted to NULL when serialized.

JSON.stringify({ foo: NaN.id: 1 }) // {"foo":null,"id":1}
JSON.stringify([null.Infinity.NaN]) // [null,null,null]
JSON.stringify(NaN) // null
JSON.stringify(2E+10308) // null
Copy the code

Packaging object

A wrapper object for a Boolean, value, or string that is converted to its original value when serialized.

JSON.stringify({ foo: new String('foo'), bar: new Number(123), baz: new Boolean(true)})// {"foo":"foo","bar":123,"baz":true}
JSON.stringify([new String('foo'), new Number(123), new Boolean(true)]) // ["foo",123,true]
JSON.stringify(new String('foo')) // "foo"
Copy the code

Serialization order

Properties that are not array objects that do not guarantee the order in which they appear in a serialized string.

JSON.stringify({ foo: 'foo'.3: 'bar'.1: 'baz' })) // {"1":"baz","3":"bar","foo":"foo"}
Copy the code

toJSON

If the serialized object contains a toJSON method, the return value of the toJSON method is serialized.

const array = [1.2.3]
array.toJSON = () = > 'hello'
JSON.stringify(array) // "hello"

JSON.stringify({
  bar: 'bar'.foo: {
    toJSON() {
      return NaN}}})// {"bar":"bar","foo":null}
Copy the code

The Date object deploys the toJSON method, which is called when serialized.

const date = new Date()
date.toJSON() / / the 2022-01-04 T03: stablished. 852 z
JSON.stringify(date) / / "the 2022-01-04 T03: stablished. 852 z"
Copy the code

Enumerated attribute

When serializing an object, only enumerable properties are serialized.

const object = {}
Object.defineProperties(object, {
  foo: {
    value: 'foo'.enumerable: false
  },
  bar: {
    value: 'bar'.enumerable: true}})// {bar: "bar", foo: "foo"}
JSON.stringify(object) // {"bar":"bar"}
Copy the code

A circular reference

An error is thrown when serialized.

const foo = {}
const bar = {
  foo
}
foo.bar = bar
JSON.stringify(foo)
Copy the code

Symbol attribute

Symbol as the property key is ignored, even if it is mandatory in the replacer parameter.

const object = {
  bar: 'bar'[Symbol('foo')]: 'foo'
}
JSON.stringify(object, (k, v) = > {
  if (typeof k === 'symbol') {
    return v
  }
  return v
}) // {"bar":"bar"}
Copy the code

Re and error objects

Regular expressions or error objects are converted to empty objects during serialization.

const object = {
  bar: 'bar'.reg: /a+/,
  err: new Error('err')}JSON.stringify(object) // {"bar":"bar","reg":{},"err":{}}
Copy the code

Prototype chain

If the key value in an Object is an instance of a constructor, serialization resets the Object’s constructor to Object.

function Person(key) {
  this.key = key
}
const object = {
  id: 1.foo: new Person('foo')}const copy = JSON.parse(JSON.stringify(object))
object.foo.constructor ƒ Person(key) {this.key = key}
copy.foo.constructor ƒ Object() {[native code]}
Copy the code

parameter

The second parameter, replacer

The second argument can be a function or an array.

As an array, only the property names in the array are serialized.

const object = {
  id: 1.foo: 'foo'.bar: 'bar'.baz: 'baz'
}
JSON.stringify(object, ['id'.'foo']) // {"id":1,"foo":"foo"}
Copy the code

When used as a function, the function takes two arguments, key and value. But the first time, the key is an empty string and the value value is the object stringify.

const object = {
  id: 1.foo: 'foo',}JSON.stringify(object, (key, value) = > {
  console.log(key, '/', value)
  return value
})
// / {id: 1, key: "foo"}
// id / 1
// key / foo
Copy the code

The third parameter, space

The third parameter beautifies the output by controlling the spacing of strings in the result.

const object = {
  id: 1.key: 'foo',}JSON.stringify(object, undefined.2)
/ / {
// "id": 1,
// "key": "foo"
// }
Copy the code

JSON.parse

Json. parse is used to parse JSON strings into JavaScript values or objects.

JSON.parse('{}') / / {}
JSON.parse('true') // true
JSON.parse('[1, "foo"]') // [1, "foo"]
JSON.parse('null') // null
Copy the code

The second optional argument, reviver function, also includes two arguments, key and value. The parse order is from inside out. The last time, the key is an empty string and the value value is the current parse value.

const stringify = '{"id":1,"model":{"bar":"baz"},"list":["foo"]}'
JSON.parse(stringify, (key, value) = > {
  console.log(key, '/', value)
  return value
})
// id / 1
// bar / baz
// model / {bar: "baz"}
// 0 / foo
// list / ["foo"]
// / {id: 1, model: {... }, list: Array(1)}
Copy the code

Arrays are also objects, special in that indexes are keys

Q&A

How do I serialize ES6 Map types

As with regular and error objects, Map types are converted to empty objects when serialized.

const object = {
  id: 1.map: new Map([['id'.1], ['value'.'foo']])}JSON.stringify(object) // {"id":1,"map":{}}
Copy the code

Is it possible to keep Map data as an array when Stringify is used?

Of course there is, using the second parameter, replacer.

const replacer = (key, value) = > {
  if (value instanceof Map) {
    return {
      dataType: 'Map'.value: [...value.entries()]
    }
  }

  return value
}
const stringify = JSON.stringify(object, replacer) // {"id":1,"map":{"dataType":"Map","value":[["id",1],["value","foo"]]}}
Copy the code

Note that the dataType is specified so that parse can better recover from the original object.

const reviver = (key, value) = > {
  if (typeof value === 'object'&& value ! = =null) {
    if (value.dataType === 'Map') {
      return new Map(value.value)
    }
  }
  return value
}
JSON.parse(stringify, reviver) // {id: 1, map: Map(2)}
Copy the code

summary

JSON. Stringify characteristics.

  • undefined, function orSymbolIs lost as an object property value. Is returned as an array elementundefined. When serialized separately, convert tonull
  • null,InfinityThe value of the format orNaN, will serialize tonull
  • Boolean, numeric, and string wrapper objects that are converted to their original values when serialized
  • Non-array objects do not guarantee the order of their attributes after serialization
  • Object containstoJSONMethod, then will betoJSONMethod to perform serialization (DateThe instance is deployedtoJSONMethods)
  • Only enumerable properties of the object are serialized
  • An object referenced by a loop that will throw an error when serialized
  • In order toSymbolIs ignored as a property key
  • Re, error objects, and so on will be converted to empty objects
  • If the key value in an object is an instance of a constructor, serialization resets the constructor of the object toObject

🎉 is at the end

🍻 fellows, if you have seen this article and think it is helpful to you, please like 👍 or Star ✨ to support it!

Manual code word, if there is an error, welcome to the comment area correction 💬~

Your support is my biggest motivation to update 💪~

GitHub, Blog, nuggets, CSDN synchronous updates, welcome to pay attention to 😉~