preface

JSON format is now very important in Web development, especially in the process of developing projects using Ajax, where you often need to return the JSON format string of the back-end response to the front end, which parses the JS object value (JSON object), and render the page. In the process of data transmission, JSON is passed in the form of text, namely string, while JS operates on JSON object, so the conversion between JSON object and JSON string is the key.

1. The JSON format

Briefly, the JSON format is a way to represent a set of “values” that are members of an array or object.

For this series of “values”, there are several formats:

  • The value of each member of an array or object, either a simple value or a compound value.

  • There are four types of simple values: string, numeric (which must be in decimal), Boolean, and NULL (NaN, Infinity, -infinity, and undefined are all converted to NULL).

  • Compound values come in two types: JSON-formatted objects and JSON-formatted arrays.

  • You cannot add a comma after the last member of an array or object.

  • Strings in arrays or objects must be in double quotes, not single quotes.

  • Object member names must be in double quotes.

Here are the qualified JSON values:

[" one ", "two", "three"] {" one ": 1," two ": 2," three ": 3} {" names" : [" zhang ", "li si"]} [{" name ":" * * "}, {" name ":" bill "}]Copy the code

The following JSON values are not acceptable:

{name: "triple ", 'age': 32} // Attribute name must use double quotation marks [32, 64, 128, 0xFFF] // Hexadecimal value cannot be used {"name":" triple ", 'age': 32} {"name": "zhang SAN ", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() { return this.name; }} // Can't use function and date objectsCopy the code

Note ⚠ ️ :

An empty array and an empty object are qualified JSON values, and NULL itself is also a qualified JSON value.

2. Parse the JSON

All modern browsers support JSON objects, and there are two very useful ways to handle jSON-formatted content:

Json.parse (string) : Takes a JSON string and converts it to a JavaScript object. Json.stringify (obj) : Takes a JavaScript object and converts it to a JSON string.

2.1 JSON. Stringify ()

When writing JavaScript, we use json.stringify to represent an object by serializing a value to a string value.

Chestnut:

JSON.stringify({ name: "Samara", country: "Jimbabwe" }); "{"name":"Samara","country":"Jimbabwe"}" json.stringify ("Oh look, a string!") ); // Output result: ""Oh look, a string!" "JSON. Stringify ([1, 2," open ", "the", "feel"]); // output: "[1,2,"open","the","door"]"Copy the code

Note ⚠ ️ :

  1. Undefined values, functions, or XML values are ignored
  2. If your array contains undefined, function, or XML values, those values in the array will be treated as null

Here’s another chestnut:

JSON.stringify({ doStuff: function() { }, doThings: [ function() {}, undefined ] }); "{"doThings":[null,null]}"Copy the code

Analysis:

In the above code, the original object’s doStuff property is a function, and the string returned by the json. stringify method will omit this property. The doThings property is an array of functions and undefined, both of which are converted to null.

The regular object is converted to an empty object.

JSON.stringify(/foo/) // "{}"
Copy the code

The json. stringify method ignores the non-traversable property of the object

var obj = {};
Object.defineProperties(obj, {
  'foo': {
    value: 1,
    enumerable: true
  },
  'bar': {
    value: 2,
    enumerable: false
  }
});

JSON.stringify(obj); // {"foo":1}
Copy the code

When an object’s properties are set to non-traversable, using json. stringify ignores these properties. In the above code, bar is a non-traversable property of the obj object, and the json. stringify method ignores this property.

2.1.2 Second argument to the json. stringify method

1. JSON.stringifyMethod can also take an array argument, specifying the properties that need to be turned into a string.
JSON.stringify({ a:1, b:2 }, ['a'])
// '{"a":1}'
Copy the code

Analysis:

In the above code, the second argument to the json. stringify method specifies that only the a attribute is transferred.

The json. stringify method can also take a function as an argument to change the default stringized behavior.
function f(key, value) {
  if (typeof value === "number") {
    value = 2 * value;
  }
  return value;
}

JSON.stringify({ a:1, b:2 }, f)
// '{"a":2,"b":4}'
Copy the code

The f function in the above code takes two arguments, the key and the value of the converted object.

If the value of a key is numeric, it is multiplied by 2, otherwise it is returned as is.

What does it do with multi-level nested objects?

Point 1: This handler actually recurses all the keys.

Here’s an interesting chestnut:

var o = {a: {b:1}};

function f(key, value) {
  console.log("["+ key +"]:" + value);
  return value;
}

JSON.stringify(o, f)
// []:[object Object] 
// [a]:[object Object]
// [b]:1
// '{"a":{"b":1}}'

Copy the code

Analysis:

In the above code, object o is processed by f a total of three times. The first time the key name is null, the key value is the whole object o; The second key is named a, and the key is {b:1}; The third key is b, and the key is 1.

Point two: in recursive processing, each time the object is processed, is the value returned by the previous.

var o = {a: 1};

function f(key, value){
  if (typeof value === "object"){
    return {b: 2};
  }
  return value*2;
}

JSON.stringify(o,f)
// '{"b":4}'
Copy the code

In the above code, the f function modifies the object o, and then the json. stringify method recurses the modified object o.

Point 3: If the handler returns undefined or does not return a value, this property is ignored.

function f(key, value) {
  if (typeof(value) == "string") {
    return undefined;
  }
  return value;
}

JSON.stringify({ a:"abc", b:123 }, f)
// '{"b":123}'
Copy the code

Analysis:

In the above code, the a attribute is processed and returns undefined, so the attribute is ignored.

The third argument to the json. stringify method

Json.stringify can also take a third argument that increases the readability of the returned JSON string.

If it is a number, it indicates the number of Spaces (up to 10) added before each attribute. If it is a string (no more than 10 characters), the string is appended to the front of each line.

(1) when the third argument is a number

The following example is when the third argument is a number:

Var person = {name: "Jim Cowart", location: {city: {name: "Chattanooga", population: 167674 }, state: { name: "Tennessee", abbreviation: "TN", population: 6403000 } }, company: "appendTo" }; Json.stringify (person) // We get data '{"name":"Jim Cowart","location":{"city":{"name":"Chattanooga","population":167674},"state":{"name":"Tennessee","abbreviation":"TN","p Opulation ":6403000}},"company":"appendTo"}' // We expect the format "{"name": "Jim Cowart", "location": {"city": {"name": "Chattanooga", "population": 167674 }, "state": { "name": "Tennessee", "abbreviation": "TN", "population": 6403000 } }, "company": "appendTo" }"Copy the code

If we get a piece of data but it’s not very readable, and we want it to be in the more readable format we want, we use the third argument of json.stringify.

var person = { name: "Jim Cowart", location: { city: { name: "Chattanooga", population: 167674 }, state: { name: "Tennessee", abbreviation: "TN", population: 6403000 } }, company: "appendTo" }; // If you want the indent to be 2 Spaces, you can do this: json.stringify (person, null, 2); /* produces: "{ "name": "Jim Cowart", "location": { "city": { "name": "Chattanooga", "population": 167674 }, "state": { "name": "Tennessee", "abbreviation": "TN", "population": 6403000 } }, "company": "AppendTo"}" */ // If you wish to use TAB indentation, then // you can say goodbye to space indentation by passing \t as the third argument //. Stringify (person, null, "\t"); /* Output: "{"name": "Jim Cowart", "location": {"city": {"name": "Chattanooga", "population": 167674}, "state": { "name": "Tennessee", "abbreviation": "TN", "population": 6403000 } }, "company": "appendTo" }" */Copy the code

The second argument can be either an array or a function.

If the second argument is an array, it will only print the keys you want to include in that array.

Json.stringify (person, ["name", "company"], 4); / * output: "{" name" : "Jim Cowart", "company" : "appendTo"} "* /Copy the code

If the second argument is a function, then the function needs to take two arguments: key and value:

// a bit contrived, but it shows what's possible // FYI - The serialized value is the first thing passed to replacerFn, that is, every key in this object, so you need to check for keys. var replacerFn = function(key, value) { if(! key || key === 'name' || key === 'company') { return value; } return; } json. stringify(person, replacerFn, 4); // Return undefined and ignore} json. stringify(person, replacerFn, 4); /* produces: "{ "name": "Jim Cowart", "company": "appendTo" }" */Copy the code
(2) when the third argument is a string

There is another case where the third argument is a string:

JSON.stringify({ p1:1, p2:2 }, null, "|-");
// "{
|-"p1": 1,
|-"p2": 2
}"

Copy the code

2.1.4 Object handled by the json. stringify method, including a toJSON method

If the object handled by the json. stringify method contains a toJSON method, it uses that method to get a value and then converts that value to a string, ignoring the other members.

JSON.stringify({ toJSON: function() { return "Cool" } }) // "Cool"" var o = { foo: 'foo', toJSON: function() { return 'bar'; }}; var json = JSON.stringify({x: o}); // '{"x":"bar"}'Copy the code

The Date object deploys its own toJSON method.

JSON. Stringify (new Date (" 2011-07-29 ")) / / "the 2011-07-29 T00:00:00. 000 z"Copy the code

One application of the toJSON method is the ability to automatically convert regular objects into strings.

RegExp.prototype.toJSON = RegExp.prototype.toString;

JSON.stringify(/foo/)
// "/foo/"

Copy the code

In the code above, the toJSON method is deployed on the prototype of the regular object. It points to the toString method, so when the object is converted toJSON, the toJSON method is called to turn the regular object into a string, which is then handled by the json.stingify method.

2.2 JSON. The parse ()

The json. parse method is used to convert a JSON string into an object.

JSON.parse('{}') // {} JSON.parse('true') // true JSON.parse('"foo"') // "foo" JSON.parse('[1, 5, "false"]') // [1, 5, "False"] JSON. Parse (' null ') / / null var. O = JSON parse (' {" name ":" * * "} "); O.n ame / / zhang SANCopy the code

The json.parse method will report an error if the string passed in is not a valid JSON format.

JSON.parse("'String'") // illegal single quotes
// SyntaxError: Unexpected token ILLEGAL

Copy the code

In the above code, the double quoted string is a single quoted string, because the single quoted string does not conform to the JSON format, so an error is reported.

To handle parsing errors, place the json. parse method in the try… Catch block.

The second argument to 2.2.1 json.parse ()

The json. parse method can accept a handler function that is used similarly to the json.stringify method.

function f(key, value) {
  if ( key === ""){
      return value;
  }
  if ( key === "a" ) {
    return value + 10;
  }
}

var o = JSON.parse('{"a":1,"b":2}', f);
o.a // 11
o.b // undefined
Copy the code

Closed…

Do you think we can do a lot of things with these two methods?