对于JSON,相信你们应该都蛮熟悉的.无论是前端仍是后端的童鞋,应该天天都会和JSON打交道吧.JSON是 JavaScript Object Notation(JavaScript对象表示法)的缩写,是一种轻量级的文本数据交换格式,比xml更小,更快,更易于解析javascript
在JavaScript中,JSON对象包含两个方法,parse()
和stringify()
,前者用于反序列化,后者用于序列化.所谓的序列化,通俗的理解就是将一个对象变成字符串,而反序列化就是相对应相反的过程.前端
今天咱们主要来说讲其中的stringify()
方法.虽然咱们平时也都在用这个方法,可是咱们每每会忽略这个方法的更进一步的用法.假如咱们能用好这个方法,在实际的开发过程当中就能够达到事半功倍的效果.java
相信你们在平时的开发过程当中,常常会用到console.log
来打印输出结果.好比咱们在下面打印一个对象:json
let obj = {
name:'zhangsan',
age:undefined
}
console.log(obj) // // {name: "zhangsan", age: undefined}
复制代码
能够很清晰的在控制台输出结果,达到咱们想要的结果.可是假如咱们对象中的有的属性值是没有意义的.好比下面的代码中,年纪是个未定义的属性,咱们不想要在控制台输出它该怎么办.这时就可使用JSON.stringify()
方法来达到过滤的目的后端
let obj = {
name:'zhangsan',
age:undefined
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan"}
复制代码
咱们能够看到此时的输出结果就已经把属性值为undefined
这个age
属性给过滤掉了.而这正是JSON.stringify()
的其中一个特性.除了undefined
之外,属性值为任意函数或者symbol
类型的,也会被过滤掉.数组
let obj = {
name:'zhangsan',
age:undefined,
f:() => { console.log(1) },
symbol:Symbol('This is a symbol')
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan"}
复制代码
咱们再来给这个对象添加一个属性.此次咱们添加的是一个数组,而这个数组里面就有一些上面咱们提到过的这些类型,结果又是如何呢?函数
let obj = {
name:'zhangsan',
age:undefined,
f:() => { console.log(1) },
symbol:Symbol('This is a symbol'),
arr:[1, undefined, 2, this.f, 3, Symbol('This is a symbol in array')]
}
console.log(JSON.stringify(obj)) // {"name":"zhangsan","arr":[1,null,2,null,3,null]}
复制代码
能够看到,undefined
,函数和symbol
类型的都变成了null
. 下面咱们还要用这几个类型来测试,假如咱们直接使用JSON.stringify()
来操做它们会怎么样呢?测试
console.log(JSON.stringify(undefined)) // undefined
console.log(JSON.stringify(() => { console.log(1) })) // undefined
console.log(JSON.stringify(Symbol('This is a symbol'))) // undefined
复制代码
能够看到输出结果全是undefined
.咱们再来看看其余的某些特殊的值:ui
console.log(JSON.stringify(null)) // null
console.log(JSON.stringify(NaN)) // null
console.log(JSON.stringify(Infinity)) // null
复制代码
能够看到null
,NaN
,Infinity
之类的都变成了null
.this
下面咱们来看看转换包装对象的结果
console.log(JSON.stringify(new String('str'))) // "str"
console.log(JSON.stringify(new Boolean(true))) // true
console.log(JSON.stringify(new Number(1))) // 1
复制代码
能够看出字符串,布尔类型和数字的包装对象会在序列化的时候变成原始值
假如咱们转换对象中有toJSON
这个方法,那么返回的结果就由它决定:
let obj = {
name:'zhangsan',
toJSON:function(){
return 'customize return value'
}
}
console.log(JSON.stringify(obj)) // "customize return value"
复制代码
若是显示的定义了toJSON
方法却没有return
任何内容,那么结果就是undefined
let obj = {
name:'zhangsan',
toJSON:function(){}
}
console.log(JSON.stringify(obj)) // undefined
复制代码
这里又能够牵扯出另一个对象类型Date
.假如咱们序列化一个Date
类型,结果又是什么呢?
console.log(JSON.stringify(new Date())) // "2020-06-20T14:21:15.071Z"
复制代码
能够看到输出了这种咱们熟悉的时间格式,这是由于Date
类型的对象就有本身的toJSON
的实现
假如一个对象的属性是不可枚举的,那么也会被过滤掉
let obj = Object.create({},{
name:{
value:'zhangsan',
enumerable:false
},
age:{
value:18,
enumerable:true
}
})
console.log(obj) // {age: 18, name: "zhangsan"}
console.log(JSON.stringify(obj)) // {"age":18}
复制代码
到上面为止,咱们举例了一些JSON.stringify()
的用法.不少人觉得到这里就结束了,其实不是的,下面咱们还要介绍它的第2个参数.
假若有这么一个对象,它有姓名,性别,年纪等多种属性.可是咱们不想关心它的其余信息,只想知道它的名字是啥.而它的其余属性值都不是像那些undefined
等同样是无心义的值,咱们该如何过滤呢?
let obj = {
name:'zhangsan',
gender:'female',
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj,['age'])) // {"age":18}
复制代码
这时,咱们的第2个参数就派上用场了.咱们传入了一个数组,而这个数组中的值就是咱们想要保留的属性名,不在这个数组之列的,所有都不要返回. 除了传入数组类型之外,咱们还能够传入一个函数.
let obj = {
name:'zhangsan',
gender:undefined,
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'string'){
return undefined
}
return value
})) // {"age":18}
复制代码
在函数中,咱们作了一些逻辑判断,当属性值是字符串的时候,就给它过滤掉.使用这第二个参数,咱们也能够改变属性值为undefined
,symbol
之类的本来不会返回的属性.
let obj = {
name:'zhangsan',
gender:undefined,
age:18,
hobby:'swim'
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'string'){
return undefined
}
if(typeof value === 'undefined'){
return 'not any more undefined'
}
return value
})) // {"gender":"not any more undefined","age":18}
复制代码
再来结合toString()
这个方法,咱们来输出函数的具体内容:
let obj = {
name:'zhangsan',
f:function(){
console.log('I\'m a function')
}
}
console.log(JSON.stringify(obj, (key, value) => {
if(typeof value === 'function'){
return Function.prototype.toString.call(value)
}
return value
}))
// {"name":"zhangsan","f":"function(){\n console.log('I\\'m a function')\n }"}
复制代码
讲完了第2个参数,咱们再来说讲第3个参数.是的,你没有看错,它还有第三个参数.这个参数的主要做用是用来美化输出的json字符串.在没有第三个参数的时候,咱们输出的字符串是挤在一堆的,不利于观看.有了它,咱们就能够格式化咱们的输出结果:
let obj = {
name:'zhangsan',
age:18,
gender:'female'
}
console.log(JSON.stringify(obj,null,2))
/*{ "name": "zhangsan", "age": 18, "gender": "female" }*/
复制代码
第三个参数传入的类型是数字n的话,就表示每一级比它的上一级多缩进n个空格,n最大为10 第三个参数传入的类型是字符串的话,则会在每一级前面加上这个字符串,字符串的最大长度也是10
let obj = {
name:'zhangsan',
age:18,
gender:'female'
}
console.log(JSON.stringify(obj,null,'😊'))
/*{ 😊"name": "zhangsan", 😊"age": 18, 😊"gender": "female" }*/
复制代码
总结: 至此,关于JSON.stringify()
的用法,咱们基本讲的差很少了.大部分的知识点咱们就用下面的图来表示了.