Let’s first look at a common JS object serialization into JSON strings in JS. What is the string after the following JS object passes? Don’t rush to copy and paste it to the console first. First, open a code editor or paper yourself, write and read it, and then carefully compare your console output after writing. If there is any error, remember to read the complete text and comment, haha.
var friend={ firstName: 'Good', 'lastName': 'Man', 'address': undefined, 'phone': ["1234567",undefined], 'fullName': function(){ return + ' ' + ; } }; (friend);//What does this line return?
The second question is, if I want to turn all the names of this 'friend' into capital letters in the final JSON string, that is, turn "Good" into "GOOD" and "Man" into "MAN", then how can I do it?
Based on the above two questions, let’s trace the origin and ask, what exactly is JSON? Why is JSON easy to exchange data? What is the difference between JSON and JS objects? In JS、
and uncommon
toJSON
, What are the parameters and processing details of these functions?
Welcome to this "Diverful JSON Journey". The following article will understand JSON from the following aspects:
- First of all, it is the understanding of "JSON is a lightweight data exchange format";
- Then look at the difference between JSON and JS objects that are often confused;
- Finally, let’s look at the specific execution details of these JSON-related functions in JS.
I hope the full text can make JSON who has only a little knowledge of JSON as I did before, and can also be proficient in using JSON. You can know what the output is after JS object is serialized into JSON strings without looking at the console.
1. JSON is a format based on text, better than lightweight, used to exchange data
If you haven't been to JSON's official introduction, you canGo hereThe first and second paragraphs of the official introduction have clearly stated what JSON is. I have refined what JSON is into the following aspects:
1. A data format
What is format? It is to regulate how your data should be expressed. For example, there is a person called "26", "160cm", and "60kg". Now you have to pass on this person's information to others or something else. You have many choices:
- Name "26", height "160cm", weight "60kg"
- name="26"&height="160cm"&weight="60kg"
- <person><name>Two hundred and six</name><height>160</height><weight>60</weight></person>
- {"name":"Two hundred and six","height":160,"weight":60}
- ... ...
All the above choices, the data passed is the same, but you can see that the forms can be of various types. This is the various formatted data, and JSON is one of the representations.
2. Text-based data format
JSON is a text-based data format. Compared with binary-based data, JSON is passed on a string that conforms to the JSON format (as for what the JSON format is, we will talk about it in the second part), which we often call is "JSON string".
3. Lightweight data format
Before JSON, there was a data format called xml, which is still widely used now, but JSON is more lightweight. For example, xml requires a lot of tags. In the example above, you can clearly see that the tag itself occupies a lot of space in the data in the xml format, while JSON is lighter, that is, the same data occupies a smaller bandwidth in the JSON format, which has obvious advantages when there are a large amount of data requests and transmissions.
4. It is widely used in data exchange
Lightweight is already an advantage for data exchange, but more importantly, JSON is easy to read, write and machine parsing, that is, this JSON is friendly to both humans and machines, and is light and language-independent (because it is text-based), so JSON is widely used in data exchange.
The front-end JS performs ajax POST request as an example, and the back-end PHP process request as an example:
- The front-end constructs a JS object to wrap the data to be passed, then converts the JS object into a JSON string, and then sends a request to the back-end;
- The backend PHP receives this JSON string, converts the JSON string into a PHP object, and then processes the request.
It can be seen that there are three different manifestations of the same data here, namely the front-end JS object, the transmitted JSON string, and the back-end PHP object. The JS object and the PHP object are obviously not the same thing, but since everyone uses JSON to pass data, everyone can understand this data format and can easily convert the JSON data format into a data structure that they can understand. This is convenient, and the same is true for exchanging data in various other locale environments.
2. "Gossip" between JSON and JS objects
Many times I hear the saying "JSON is a subset of JS", and I have always thought that it is OK to parse every string that conforms to JSON format into js, until I discovered something strange...
1. Why are two essentially different things so close
JSON and JS objects are essentially not the same thing, just like "zebra crossings" and "zebra crossings". "zebra crossings" are presented and named based on the stripes of the "zebra", but zebras are alive and zebra crossings are non-biological.
Similarly, "JSON" has the full name "JavaScript Object Notation", so its format (syntax) is based on JS, but it is a format, and the JS object is an instance, something that exists in memory.
To be a joke, if JSON is based on PHP, it may be called PON, and the form may be like this ['propertyOne' => 'foo', 'propertyTwo' => 42,]. If so, then JSON may be closer to PHP now.
In addition, JSON can be transferred because it is in text format, but JS objects cannot be transferred. In terms of syntax, JSON will be more stringent, but JS objects are very loose.
So why are two different things so close, because JSON evolved from JS after all, and the syntax is similar.
2. What is the strict syntax performance of JSON format?
First, let’s compare the differences between the two in the form of “key-value pairs as objects expressed”. As for what form JSON can be expressed, we will list them after the comparison.
Comparison content | JSON | JS Objects |
---|---|---|
Key name |
Must be double quotes |
It is allowed to add no, single, double quotes |
Attribute value |
It can only be numeric values (decimal), strings (double quotes), boolean values and null. |
Whatever you love |
Comma question |
There cannot be a comma after the last property |
Can |
Value |
The leading 0 cannot be used, there must be a number after the decimal point |
No restrictions |
It can be seen that compared with JS objects, the format of JSON is more stringent, so most of the written JS objects do not conform to the format of JSON.
The following code is quoted fromhere
var obj1 = {}; // This is just a JS object // This can be called: a JavaScript object in JSON formatvar obj2 = {"width":100,"height":200,"name":"rose"}; // This can be called: JSON format stringvar str1 = '{"width":100,"height":200,"name":"rose"}'; // This array, which can be called JSON format, is a slightly more complex form of JSONvar arr = [ {"width":100,"height":200,"name":"rose"}, {"width":100,"height":200,"name":"rose"}, {"width":100,"height":200,"name":"rose"}, ]; // This can be called a slightly more complex string in JSON formatvar str2='['+ '{"width":100,"height":200,"name":"rose"},'+ '{"width":100,"height":200,"name":"rose"},'+ '{"width":100,"height":200,"name":"rose"},'+ ']';
In addition, except for the common "normal" JSON format, it either appears as an object form {...} or an array form [...], any single decimal value, double quoted string, boolean value, and null are effectively in line with JSON format.
Here is a complete JSON syntax reference
3. An interesting place, JSON is not a subset of JS
First look at the following code, you can copy it to the console and execute it:
var code = '"\u2028\u2029"'; (code); // works fine eval(code); // fails
These two characters \u2028 and \u2029 represent line separators and paragraph separators respectively, which can be parsed normally, but an error will be reported when parsing as JS.
3. What are you doing in these JSON functions?
In JS, we will mainly come into contact with two functions related to JSON, which are used to transform between JSON strings and JS data structures. One is called, it is very smart, so clever that you write JS objects that do not conform to JSON format can help you process them into strings that conform to JSON format, so you have to know what it does, so as not to be smart enough to make you think you are just doing it.
, used to convert json strings to JS data structures. It is very strict. If your JSON string is constructed incorrectly, it cannot be parsed.
And they have more than one parameter, although we often use it only pass in one parameter.
In addition, there is a toJSON function that we rarely see, but it will affect。
1. Convert JS data structures into JSON strings—
The function signature of this function is as follows:
(value[, replacer [, space]])
The following will expand the usage of 1 to 3 parameters respectively, and finally some "smart" things it does during serialization, so pay special attention to it.
1.1 Basic use-only one parameter is required
Everyone will use this to pass in a JSON format JS object or array.({"name":"Good Man","age":18})
Return a string"{"name":"Good Man","age":18}"
。
You can see that the JS object we passed in is in line with JSON format, and it uses double quotes, and does not have attribute values that JSON does not accept. So if it is like in the example at the beginning, how to play? No hurry, let’s first give a simple example to illustrate the significance of several parameters of this function, and then talk about this issue.
1.2 The second parameter can be a function or an array
- If the second parameter is a function, then every property in the serialization process will be converted and processed by this function
- If the second parameter is an array, only the properties contained in this array will be serialized into the final JSON string
- If the second parameter is null, then there is no difference between function and being empty. However, if you don’t want to set the second parameter, you just want to set the third parameter, you can set the second parameter to null
If this second parameter is a function
var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; var friendAfter=(friend,function(key,value){ if(key==="phone") return "(000)"+value; else if(typeof value === "number") return value + 10; else return value; //If you delete this else clause, the result will be undefined}); (friendAfter); //Output:{"firstName":"Good","lastName":"Man","phone":"(000)1234567","age":28}
If the second parameter is made, the function must return each item. This function accepts two parameters, one is the key name and the other is the attribute value. The function must return the new attribute value for each original attribute value.
Then the question is,What if the object form of a key-value pair is passed in is not a key-value pair, but an array form of square brackets? , for example, the friend above becomes like this:friend=["Jack","Rose"]
, then what are the key and value received by this attribute-by-property function? If it is in an array form, then the key is the index and the value is the array item. You can print out the key and value verification inside this function in the console.
If this second parameter is an array
var friend={ "firstName": "Good", "lastName": "Man", "phone":"1234567", "age":18 }; //Note that the following array has a value that is not any of the attribute names of the above objectvar friendAfter=(friend,["firstName","address","phone"]); (friendAfter); //{"firstName":"Good","phone":"1234567"} //Specified“address”Ignored because it was not found in the original object
If the second parameter is an array, only the attributes that appear in the array will be serialized into the result string. As long as the attributes that cannot be found in the provided array will not be included. Attributes that exist in this array but do not exist in the source JS object will be ignored and no error will be reported.
1.3 The third parameter is used to beautify the output - not recommended
To specify the blank characters for indentation, you can take the following values:
- It is a number from 1-10, which means that several blank characters are used.
- If it is a string, use the string instead of spaces, and take the first 10 characters of the string at most.
- This parameter is not provided. Set to null. Set a number less than 1.
var friend={ "firstName": "Good", "lastName": "Man", "phone":{"home":"1234567","work":"7654321"} }; //Direct conversion is like this://{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":"7654321"}} var friendAfter=(friend,null,4); (friendAfter); /* { "firstName": "Good", "lastName": "Man", "phone": { "home": "1234567", "work": "7654321" } } */ var friendAfter=(friend,null,"HAHAHAHA"); (friendAfter); /* { HAHAHAHA"firstName": "Good", HAHAHAHA"lastName": "Man", HAHAHAHA"phone": { HAHAHAHAHAHAHAHA"home": "1234567", HAHAHAHAHAHAHAHA"work": "7654321" HAHAHAHA} } */ var friendAfter=(friend,null,"WhatAreYouDoingNow"); (friendAfter); /* Only 10 characters are taken at most { WhatAreYou"firstName": "Good", WhatAreYou"lastName": "Man", WhatAreYou"phone": { WhatAreYouWhatAreYou"home": "1234567", WhatAreYouWhatAreYou"work": "7654321" WhatAreYou} } */
Just smile,Don't use this. Serialization is for transmission. The smaller the transmission, the better. Adding inexplicable indentation symbols makes it difficult to parse (if it is a string), and also weakens the characteristic of lightweighting.
1.4 Pay attention to the "smart" of this function (important)
If there are other uncertain situations, the best way is to "have a try" and the console will be clear.
-
The key name is not double quotes (including without quotes or single quotes), and will automatically become double quotes; the string is single quotes and will automatically become double quotes.
-
If the last attribute has a comma after it will be automatically removed
-
Properties of non-array objects cannot be guaranteed to appear in serialized strings in a specific order.
This is easy to understand, that is, the attribute order of non-array objects is not guaranteed to be consistent with the original character in the final string. -
The wrapping objects of boolean values, numbers, and strings will be automatically converted into the corresponding original value during serialization.
That is, your new String("bala") will become "bala", and new Number(2017) will become 2017 -
undefined, arbitrary functions (in fact, there is a function that will happen magical things, which will be discussed later) and symbol value (see ES6's introduction to symbol for details)
- Appears in property values of non-array objects: will be ignored during serialization
- When appearing in an array: converted to null
({x: undefined, y: function(){return 1;}, z: Symbol("")}); //Occurs in property values of non-array objects and is ignored: "{}"([undefined, Object, Symbol("")]); // Appears in the property value of the array object and becomes null:"[null,null,null]"
NaN, Infinity, and -Infinity, both in arrays and non-array objects, are converted to null.
All attributes with symbol as the attribute key will be completely ignored, even if the replacer parameter is forced to include them.
Non-enumerable attributes will be ignored
2. Parsing JSON strings into JS data structures—
The function signature of this function is as follows:
(text[, reviver])
If the first parameter, that is, the JSON string is not a legal string, then this function will throw an error. Therefore, if you are writing a script that returns a JSON string backend, it is best to call the JSON string-related serialization function of the language itself. If it is a serialized string implemented by yourself, then pay special attention to whether the serialized string is legal.Legal means that this JSON string fully meets the strict format of JSON requirements.。
It is worth noting that there is an optional second parameter here. This parameter must be a function. This function works before the property has been parsed but has not been returned. It processes the property before it is returned.
var friend={ "firstName": "Good", "lastName": "Man", "phone":{"home":"1234567","work":["7654321","999000"]} }; // Let's serialize it firstvar friendAfter=(friend); //'{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":["7654321","999000"]}}' //Parse it out and print out the key and value in the function with the second parameter(friendAfter,function(k,v){ (k); (v); ("----"); }); /* firstName Good ---- lastName Man ---- home 1234567 ---- 0 7654321 ---- 1 999000 ---- work [] ---- phone Object ---- Object ---- */
If you look at these outputs carefully, you will find that this traversal is from the inside out. You may misunderstand the word "inside out". The innermost layer is two values in the internal array, but the output starts with the first attribute, so why is it from the inside out?
This refers from the inside out to the compound attribute. In layman's terms, when traversing, it is traversed from beginning to end. If it is a simple attribute value (numerical, string, boolean value and null), then the traversal is completed directly. If the attribute value is in the form of an object or array, then pause and traversal first traversal. The principle of traversal is the same. When the compound attribute traversal is completed, then the traversal return of this attribute is completed.
Essentially, this is a depth-first traversal.
There are two things to note:
- If reviver returns undefined, the current property will be deleted from the object to which it belongs. If another value is returned, the returned value will become the new property value of the current property.
- You can notice that the last set of outputs in the above example does not seem to have a key. In fact, this key is an empty string, and the last object is the final parsing object, because at the top level, there are no real attributes.
3. The magical function of influence—
If you implement the toJSON method on a JS object, then when you call to deserialize this JS object, the value returned by the toJSON method of this object will be serialized as a parameter.
var info={ "msg":"I Love You", "toJSON":function(){ var replaceMsg=new Object(); replaceMsg["msg"]="Go Die"; return replaceMsg; } }; (info); //outsiIt's,The return is:'"{"msg":"Go Die"}"',What about ignoring the function
This is how this function looks like.
In fact, the Date type can be directly passed toThe reason for making parameters is that the Date type is built-in
toJSON
method.
4. Summary and issues about compatibility
At this point, I finally sorted out JSON and JSON in JS, and also traversed the details and points of attention in it. I knew that JSON is a lightweight data exchange format syntactically derived from the JS language, and I also understood the differences between JSON compared to general JS data structures (especially objects). Further, I carefully discussed the three functions and details about JSON processing in JS.
Unfortunately, the three functions used above are incompatible with browsers before IE7 and IE7. Discussions about compatibility will be left to the future. If you want to solve compatibility directly on the application, you can apply the official JSON js to solve it.