JSON methods, toJSON
JavaScript JSON methods, toJSON (JavaScript JSON方法, toJSON)
The JavaScript Object Notation (JSON) is a notable format for representing objects and values. Initially, this format was created for JavaScript, but several languages also include libraries for handling it. Hence, it is easier to use JSON for data exchange in case the client uses JavaScript, and the server is written on PHP, Ruby, Java, and more. (JavaScript对象表示法(JSON)是表示对象和值的一种值得注意的格式。最初,这种格式是为JavaScript创建的,但几种语言还包括用于处理它的库。因此,如果客户端使用JavaScript ,并且服务器使用PHP、Ruby、Java等编写,则更容易使用JSON进行数据交换。)
In general, JavaScript provides two methods of converting: JSON.stringify and JSON.parse. You can use the first one for converting objects into JSON and the second one- for converting JSON back into an object.
JSON.stringify
JSON.stringify
Let’s consider the following example of the JSON.stringify usage:
let site = {
name: 'w3cdoc',
hasAdmin: true,
books: ['html', 'css', 'js', 'git'],
booksCount: 4,
};
let json = JSON.stringify(site);
console.log(typeof json); // we've got a string!
console.log(json);
/* JSON-encoded object:
{
"name": "w3cdoc",
"hasAdmin": true,
"books": ["html", "css", "js", "git"],
"booksCount": 4
}
*/
Please, take into account that a JSON-encoded object differs from the object literal. The main differences are as follows:
Double quotes are used by the string. There shouldn’t be any single quotes or backticks in JSON. For example, ‘w3cdoc’ becomes “w3cdoc”. Double quotes should be used for object property names, as well. It’s mandatory. For example, booksCount : 4 will become “booksCount”: 4.
You can apply the JSON.stringify method to primitives, too. It supports the following data types:
Arrays [ … ] (数组)
Objects { … }
Primitives (numbers, strings, boolean values, and null). (-基元(数字、字符串、布尔值和null )。)
Here is an example:
// a JSON number is an ordinary number
console.log(JSON.stringify(10)) // 10
// a JSON string is a double-quoted string
console.log(JSON.stringify([1, 2, 3])); // [1,2,3]
console.log(JSON.stringify(false)); // false
console.log(JSON.stringify('w3cdoc')) // "w3cdoc"
Note that JSON.stringify skips several JavaScript-specific objects, such as function properties (methods), symbolic properties, and properties storing undefined. (请注意, JSON.stringify会跳过几个特定于JavaScript的对象,例如函数属性(方法)、符号属性和存储未定义的属性。)
Let’s check out the following case:
let site = {
welcome() { // ignore
console.log("Welcome");
},
[Symbol("id")]: 10, // ignore
someProperty: undefined // ignore
};
console.log(JSON.stringify(site)); // {} - empty object
The best thing about it is that the nested objects are automatically supported and converted. (最棒的是,嵌套的对象会自动被支持和转换。)
For example:
let site = {
name: "w3cdoc",
books: {
booksCount: 4,
booksTitle: ["html", "css", "js", "git"]
}
};
console.log(JSON.stringify(site));
/* The whole structure is stringified:
{
"name":"w3cdoc",
"book":{"booksCount":4,"booksTitle":["html","css", "js", "git"]},
}
*/
But, there is an essential limitation as well: you must not use circular references.
For example:
let books = {
booksCount: 4
};
let site = {
name: "w3cdoc",
booksTitle: ["html", "css", "js", "git"]
};
site.tutorial = books; // site references books
books.canUse = site; // books references site
console.log(JSON.stringify(site)); // Error: Converting circular structure to JSON
Excluding and Transforming: replacer
Excluding and Transforming: replacer
For JSON.stringify the following full syntax is used:
let json = JSON.stringify(value[, replacer, space])
It has three arguments:
the value: a value for encoding;
the replacer: the array of properties for encoding or a mapping function function(key, value);;
the space:amount of space that is used for formatting.
JSON.stringify uses the first argument most of the time. But if you wish to improve your replacement process, you can also use the second argument. If an array of properties is passed to it, only these properties are encoded. (JSON.stringify大多数时候使用第一个参数。但是,如果您希望改进更换过程,也可以使用第二个参数。如果将属性数组传递给它,则仅对这些属性进行编码。)
Let’s have a look at the example:
let books = {
booksCount: 4
};
let site = {
name: "w3cdoc",
booksTitle: [{
title: "html"
}, {
title: "css"
}, {
title: "js"
}, {
title: "git"
}],
tutorial: books // tutorial references books
};
books.canUse = site; // books references site
console.log(JSON.stringify(site, ['name', 'booksTitle']));
// {"name":"w3cdoc","booksTitle":[{},{},{},{}]}
let books = {
booksCount: 4
};
let site = {
name: "w3cdoc",
booksTitle: [{
title: "html"
}, {
title: "css"
}, {
title: "js"
}, {
title: "git"
}],
tutorial: books // site references books
};
books.canUse = site; //books references site
console.log(JSON.stringify(site, ['name', 'booksTitle', 'tutorial', 'title', 'booksCount']));
/*
{
"name":"w3cdoc",
"booksTitle":[{"title":"html"},{"title":"css"}, {"title":"js"}, {"title":"git"}],
"tutorial":{"booksCount":4}
}
*/
Now, let’s try to add in the list all the properties, excluding the books.free:
As you can see, everything is serialized, except canUse. You can also notice that the given list looks rather long. Luckily, the replacer function can be called. You can call it for every key, value pair, and the “replaced” value may be returned. You can use it instead of the original value. For ignoring the canUse the undefined is returned in the example below:
let books = {
booksCount: 4
};
let site = {
name: "w3cdoc",
booksTitle: [{
title: "html"
}, {
title: "css"
}, {
title: "js"
}, {
title: "git"
}],
tutorial: books // site references books
};
books.canUse = site; // books references site
console.log(JSON.stringify(site, function replacer(key, value) {
console.log(`${key}: ${value}`);
return (key == 'canUse') ? undefined : value;
}));
/* key:value pairs that come to replacer:
: [object Object]
name: w3cdoc
booksTitle: [object Object],[object Object],[object Object],[object Object]
0: [object Object]
title: html
1: [object Object]
title: css
2: [object Object]
title: js
3: [object Object]
title: git
tutorial: [object Object]
booksCount: 4
*/
Take into account that the replacer function gets any key/value pair along with array items and nested objects. (请考虑replacer函数获取任何键/值对以及数组项和嵌套对象。)
Formatting:space
Formatting:space
As it was already mentioned, JSON.stringify has three arguments. The third one is the number of spaces used for formatting. Commonly, developers use the space argument to reach an excellent output. (如前所述, JSON.stringify有三个参数。第三个是用于格式化的空格数。通常,开发人员使用空间参数来获得出色的输出。)
The space = 2 orders JavaScript to display the nested objects on various lines with indentation of two spaces inside an object. (Space = 2命令JavaScript在各行上显示嵌套对象,并缩进对象内的两个空格。)
For instance:
let user = {
name: "Maria",
age: 23,
roles: {
isAdmin: true,
isContentWriter: false
}
};
console.log(JSON.stringify(user, null, 2));
/* two-space indents:
{
"name": "Maria",
"age": 23,
"roles": {
"isAdmin": true,
"isContentWriter": false
}
}
*/
/* for JSON.stringify(user, null, 2) the result would be more indented:
{
name: "Maria",
age: 23,
roles: {
isAdmin: true,
isContentWriter: false
}
};
*/
Custom “toJSON”
Custom “toJSON” (自定义“toJSON”)
As a rule, an object can provide the method toJSON for implementing the to-JSON conversion. If it’s available, the JSON.stringify automatically calls it. (通常,对象可以向JSON提供用于实现到JSON转换的方法。如果可用, JSON.stringify会自动调用它。)
Here is an example:
let books = {
booksCount: 4
};
let site = {
name: "w3cdoc",
update: new Date(Date.UTC(2020, 1, 2)),
books
};
console.log(JSON.stringify(site));
/*
{
"name":"w3cdoc",
"update":"2020-02-02T00:00:00.000Z", // (1)
"books": {"booksCount":4 } // (2)
}
*/
In the case above, the update (1) is transformed into a string. The reason is that all the dates have a built-in toJSON method. (在上述情况下, update (1)被转换为字符串。原因是所有日期都有内置的toJSON方法。)
If you add a custom toJSON for the books (2) object, it will look as follows:
let books = {
booksCount: 4,
toJSON() {
return this.booksCount;
}
};
let site = {
name: "w3cdoc",
books
};
console.log(JSON.stringify(books)); // 4
console.log(JSON.stringify(site));
/*
{
"name":"w3cdoc",
"books": 4
}
*/
JSON.parse
JSON.parse
For decoding a JSON-string another method is used, called JSON.parse with the following syntax:
let value = JSON.parse(str, [reviver]);
JSON is somewhat complicated: objects and arrays may include other objects and arrays. But it’s compulsory to obey the format of JSON.
Below, you can find the typical mistakes in hand-written JSON:
let json = `{
welcome: "Welcome", // mistake: property name without quotes
"site": 'w3cdoc', // mistake: single quotes in value (must be double)
'hasAdmin': true // mistake: single quotes in key (must be double)
"update": new Date(2000, 2, 3), // mistake: no "new" is allowed, only bare values
"books": [1, 2, 3, 4] // here all fine
}`;
Also, note that JSON doesn’t allow commenting. In case you add a comment to it, you will make it invalid. There is a unique format JSON, which supports unquoted keys, comments, and more. (此外,请注意, JSON不允许注释。如果您向其添加评论,您将使其无效。有一种独特的格式JSON ,它支持不带引号的键、注释等。)
Summary
Summary (概要)
JSON represents a data format with independent standard and libraries for the majority of programming languages. It supports arrays, strings, objects, booleans, numbers, and null. (JSON代表一种数据格式,具有独立的标准和库,适用于大多数编程语言。它支持数组、字符串、对象、布尔值、数字和null。)
JavaScript has the methods JSON.stringify for serializing into JSON and JSON.parse for reading from JSON. In case an object has toJSON, you need to call it by JSON.stringify.. (JavaScript具有用于序列化为JSON的JSON.stringify方法和用于从JSON读取的JSON.parse方法。如果对象具有toJSON ,则需要通过JSON.stringify调用它。)