功能非常简单的一个方法,但是有很多细节需要注意,本文通过代码实例详细介绍。
由此方法的名称入手,从 simplify 单词分析开始:
(1).simplify 是由 simple 衍化而来,加上 ify 后缀,变成一个动词,功能是使 ... 简单化。
(2).同样的道理,stringify 是由 string 衍化而来,加上 ify 后缀,功能是使 ... 字符串化。
JSON.stringify() 的定义是将参数转换为 JSON,其实就是将参数转换为字符串。
当然转换是需要遵循一定规则的,后面会分步进行详细介绍。
语法结构:
```javascript
JSON.stringify(value [, replacer] [, space])
```
参数解析:
(1).value:必需,要被转换的 JavaScript 值,通常情况下是对象直接量或者数组。
(2).replacer:可选,对 value 进行转换的函数或者数组。
(3).space:可选,向返回的 JSON 中的内容添加缩进、空白和换行符以使其更易于阅读。
上面对参数的作用做了一下简单介绍,让读者对其有一个初步印象,具体作用在下面代码实例中介绍。
**代码实例如下:**
绝大多数时候此方法是对对象或者数组的操作,实际项目中最为常见。
又由于此方法的操作就是将参数转换为 JSON,所以很多朋友想当然认为 JSON 只能是如下两种类似形式:
```javascript
{
"webName":"先思考后编码",
"url":"codingbefore.com",
"age":2
}
```
再来看一个和数组相互嵌套的形式:
```javascript
{
"web": [
{ "webName":"先思考后编码" , "url":"codingbefore.com" },
{ "webName":"网易" , "url":"163.com" }
]
}
```
其实并不是只有上述两种形式,看如下代码实例:
```javascript
console.log(JSON.stringify(5));
console.log(JSON.stringify(true));
console.log(JSON.stringify("antzone"));
console.log(JSON.stringify(null));
console.log(JSON.stringify(undefined));
console.log(JSON.stringify(function(){}));
console.log(JSON.stringify(Symbol("前端教程")));
```
![](/upload/1586420625277.jpg)
具有结果的都是JSON数据,并不仅仅是对象或者数组被转换后的字符串是JSON。
上述代码分析如下:
(1).数字会被转换为字符串"5"。
(2).布尔值true被转换为字符串"true"。
(3).字符串"antzone",打印结果带有双引号,字符串本身带有双引号,JSON.stringify()方法将"antzone"整体作为字符串处理,所以处理的结果是"\"antozne\"",如果是用单引号包裹,也会被转换为双引号。
(4).null会被转换为字符串"null"。
(5).undefined、function函数和Symbol数据会被忽略。
```javascript
console.log(JSON.stringify(new Date()));
```
代码运行效果截图如下:
![![](/upload/1586420596792.jpg)
打印出一段与时间日期相关的字符串,这是因为时间日期对象具有toJSON方法。
转换过程中,如果对象具有toJSON方法,那么会首先调用此方法,具体参阅[toJSON() 方法](http://www.codingbefore.com/article-8584-1.html)一章节。
```javascript
let antzone={
webName:'先思考后编码',
target:"分享互助",
age:5
}
console.log(JSON.stringify(antzone));
```
上述代码只有一个参数,可以看到属性被双引号包裹,这一点要特别注意,一定是双引号。
如果属性值原本是字符串,那么一定也要用双引号包裹,如果原来是单引号,也要转换为双引号。
```javascript
let arr=["先思考后编码",'分享互助',3];
console.log(JSON.stringify(arr));
```
类似,数组中的数据,如果原本是字符串,一定要采用双引号包裹。
**具有两个参数的情况:**
JSON.stringify()第二个参数可以是两种形式,一种是函数,第二种是数组,下面分别做一下介绍。
**1.当是函数的情况:**
具有两个参数,分别是对象属性和属性值,或者数组索引和数组值。
它的返回值对于value参数的序列化结果有直接的影响。
(1).如果返回值是undefined,那么value参数序列化的结果为 undefined 或者当前递归序列化对象的属性被删除。
(2).如果返回值是一个对象,那么该对象会被递归序列化。
```javascript
let arr=["先思考后编码","antzone",5];
function done(key,value){
}
let jsonStr=JSON.stringify(arr,done);
console.log(jsonStr);
```
上面的代码中,数组被序列化后的结果为undefined,因为第二个参数函数的返回值是undefined。
```javascript
let obj={
webName:"antzone",
age:2,
target:"分享互助",
team:{
a:"jquery专区",
b:"css专区"
}
}
function done(key,value){
if(value=="antzone"){
return undefined;
}
else{
return value;
}
}
let jsonStr=JSON.stringify(obj,done);
console.log(jsonStr);
```
属性值为"antzone",对应属性就会被删除,如果此函数返回的值是对象的话,会将此返回的对象递归序列化。
**2.当是数组的时候:**
(1).如果value参数是数组,那么第二个参数数组不起任何作用。
如果对象属性名称在数组元素中存在,那么此属性将会被保留,否则会被删除。
```javascript
let one=["先思考后编码","antzone","分享互助",3];
let two=["antzone",3];
let jsonStr=JSON.stringify(one,two);
console.log(jsonStr);
```
第二个数组参数不会起到任何作用。
```javascript
let obj={
antzone:"先思考后编码",
target:"分享互助",
age:3
}
let arr=["antzone",3];
let jsonStr=JSON.stringify(obj,arr);
console.log(jsonStr);
```
第二个参数数组会对对象属性进行过滤,如果对象属性名称在数组中存在,那么就会保留,否则删除。
**具有三个参数的情况:**
可以向返回值JSON文本添加缩进,具体规则如下:
(1).如果声明此参数,则将生成返回值文本,而没有任何额外空白。
(2).如果是数字,则返回值文本在每个级别缩进指定数目空格,如果space大于10,则缩进10个空格。
(3).如果是一些转义字符,比如“\t”,表示回车,那么它每行一个回车。
(4).如果是非空字符串,则返回值文本在每个级别字符串前面附加上返回的字符串即可。
(5).如果是长度大于10个字符的字符串,则使用前10个字符。
(6).由于这个比较简单,就不给出代码了,通常情况下,第三个参数都是省略的。
**undefined、function和Symbol处理:**
在文章的开头部分已经提到过,JSON数据不支持上述三种类型数据。
但是在不同的上下文中,JSON.stringify() 方法对它们的处理方式不同。
直接通过JSON.stringify() 方法转换三种数据,方法的返回值是undefined,也可以认为被转换为了undefined。
如果上述三种类型的值作为对象属性,那么会直接被忽略,代码如下:
```javascript
let antzone={
webName:"先思考后编码",
age:undefined,
func:function(){},
sy:Symbol("前端教程")
}
console.log(JSON.stringify(antzone));
```
可以看到值为上述三种类型的属性直接被无视了。
如果上述三种类型的值作为数组成员,那么会被转换为null,代码如下:
```javascript
let arr=["先思考后编码",undefined,function(){},Symbol("前端教程")];
console.log(JSON.stringify(arr));
```
可以看到三种类型的数据,在数组中被转换成了null。