[This is the 12th day of my participation in the Gengwen Challenge. For details, see: Gengwen Challenge]
What exactly is the json. stringify method? The MDN ** json.stringify ()** method converts a JavaScript object or value to a JSON string, optionally replacing the value if a replacer function is specified, or specifying that the replacer is an array. Optionally include only the properties specified by the array
Methods Basic introduction
- Json. stringify is a method in JSON objects that is often used in everyday development.
- A JSON object contains two methods:
- Parse () is used to parse into a JSON object.
- The other is the stringify() method used to convert an object to a JSON string.
Basic usage of the two methods.
- JSON.parse()
- The json. parse method parses a JSON string and constructs JavaScript values or objects described by the string.
- Parse (text[, reviver])
- This method takes two arguments:
- The first argument is the JSON string that needs to be parsed,
- The second argument is optional to provide the optional reviver function to transform the resulting object before returning it.
- The use of this method, along with the reviver parameter, is shown below.
const json = '{"result":true, "count":2}';
const obj = JSON.parse(json);
console.log(obj.count); / / 2
console.log(obj.result);// true
/ with the second argument /
JSON.parse('{"p": 5}'.function (k, v) {
if(k === ' ') return v; // return v if k is not null,
return v * 2; // return 2 times the value of the property
}); // {p: 10}
Copy the code
- The above code shows that we can convert a string in JSON format into an object return; With the second argument, you can manipulate the string, such as multiplying the value of the property by 2 in the example above.
- JSON.stringify()
- The json. stringify method converts a JavaScript object or value to a JSON string;
- The syntax for this method is: json.stringify (value[, replacer [, space]])
- By default, this method actually takes three arguments:
- The first parameter is mandatory, and the last two are optional but not mandatory. The first argument passed is the object to be converted;
- The second is a replacer function. If the specified replacer is an array, it optionally handles only properties that contain the array specified.
- The third argument controls the spacing in the result string, and the last two arguments are used less generally.
JSON.stringify({ x: 1.y: 2 }); // "{"x":1,"y":2}"
JSON.stringify({ x: [10.undefined.function(){}, Symbol(' ')]});// "{"x":[10,null,null,null]}"
/* An example of the second argument */
function replacer(key, value) {
if (typeof value === "string") {
return undefined;
}
return value;
}
let foo = { foundation: "Mozilla".model: "box".week: 4.transport: "car".month: 7 };
let jsonString = JSON.stringify(foo, replacer);
console.log(jsonString); // "{"week":4,"month":7}"
/* An example of the third argument */
JSON.stringify({ a: 2 }, null.""); // "{ "a" : 2 }"
JSON.stringify({ a: 2 }, null.""); // "{ "a" : 2 }"
Copy the code
- Adding the second argument, replacer: filters out the string properties in the object by substitution, and returns the result of the string properties after stringify; When multiple Spaces are passed in as the third argument, it increases the number of Spaces in the resulting string, which can be seen in the last piece of code.
How do I do it manually?
The input | The output | |
---|---|---|
Basic data types | undefined | undefined |
boolean | true/false | |
number | The value is a string | |
symbol | undefined | |
null | null | |
string | string | |
NaN and infinity | null | |
Reference data type | function | undefined |
Undefined, function, and symbol appear in array | string/null | |
RegExp | “{}” | |
Date | ToJSON () string value for Date | |
The common object |
- Serialize the return value of toJSON() if there is a toJSON() method
- If undefined, arbitrary function, and symbol values are present in the attribute value, ignore them
- All properties with symbol as the attribute key are completely ignored
|
- Json.stringify () ¶ In the above table, the data types are basically sorted out and returned by the json.stringify method, but there is one special case to be noted: executing this method on objects containing circular references (also mentioned in the deep copy section) will throw an error.
- Code logic implementation
- Use typeof to separate the basic data type from the reference data type, and then handle the different cases according to the different cases, according to the logical code as follows.
function jsonStringify(data) {
const type = typeof (data);
if(type ! = ='object') {
let result = data;
if (Number.isNaN(data) || data === Infinity) result = "null";
else if (['function'.'undefined'.'symbol'].includes(type)) return undefined;
else if (type === "string") result = `"${data}"`;
return String(result);
}
else if (type === 'object') {
if (data === null) return "null" // Typeof NULL is a special case of 'object'
else if (data.toJSON && typeof data.toJSON === 'function') return jsonStringify(data.toJSON());
else if (data instanceof Array) {
let result = [];
// If it is an array, then each item in the array may be of multiple types
data.forEach((item, index) = > (result[index] = ['undefined'.'function'.'symbol'].includes(typeof item) ? "null" : jsonStringify(item)));
result = "[" + result + "]";
return result.replace(/'/g.'"');
}
else {
// Handle normal objects
let result = [];
Object.keys(data).forEach((item, index) = > {
if (typeofitem ! = ='symbol') {
// Ignore key if it is a symbol
const type = typeof data[item]
if(type ! = ='undefined'&& type ! = ='function'&& type ! = ='symbol') {
// If the key is undefined, function, and symbol, ignore the attribute values
// result.push('"' + item + '"' + ":" + jsonStringify(data[item]));
result.push(`"${item}":${jsonStringify(data[item])}`); }}});// return ("{" + result + "}").replace(/'/g, '"');
return (` {${result}} `).replace(/'/g.'"'); }}}Copy the code
Tips:
- Since function returns ‘null’, and Typeof function directly returns the exact judgment, the overall logic of the underlying data type will be handled directly with undefined, symbol;
- Since typeof null returns ‘object’, the logic for determining null is entirely within the logic for handling the reference data type.
- As for the reference of the data type of the array, because of the array of each item of the data type has many possibilities, so in the process of processing the array and undefined, symbol, function as one of the items of the array to do a special treatment;
- Also in the final processing of ordinary objects, the key (key value) also has the same problem as the array, so we need to do special processing for the above several cases (undefined, symbol, function);
- Finally, in the process of processing ordinary objects, the problem of circular reference has not been detected. If there is a circular reference, an Error needs to be thrown.
let nl = null;
console.log(jsonStringify(nl) === JSON.stringify(nl));
// true
let und = undefined;
console.log(jsonStringify(undefined) = = =JSON.stringify(undefined));
// true
let boo = false;
console.log(jsonStringify(boo) === JSON.stringify(boo));
// true
let nan = NaN;
console.log(jsonStringify(nan) === JSON.stringify(nan));
// true
let inf = Infinity;
console.log(jsonStringify(Infinity) = = =JSON.stringify(Infinity));
// true
let str = "jack";
console.log(jsonStringify(str) === JSON.stringify(str));
// true
let reg = new RegExp("\w");
console.log(jsonStringify(reg) === JSON.stringify(reg));
// true
let date = new Date(a);console.log(jsonStringify(date) === JSON.stringify(date));
// true
let sym = Symbol(1);
console.log(jsonStringify(sym) === JSON.stringify(sym));
// true
let array = [1.2.3];
console.log(jsonStringify(array) === JSON.stringify(array));
// true
let obj = {
name: 'jack'.age: 18.attr: ['coding'.123].date: new Date(),
uni: Symbol(2),
sayHi: function() {
console.log("hi")},info: {
sister: 'lily'.age: 16.intro: {
money: undefined.job: null}}}console.log(jsonStringify(obj) === JSON.stringify(obj)); // true
Copy the code
Tasking
- Logical judgment Try to use switch refactoring
- Type robustness and fault tolerant handling
Our jsonStringify method is basically the same as json. stringify. JsonStringify basically meets the expected result.