JSON的使用之灵活版
前言
JSON在正常开发的时候我们经常能够遇到,但是一般情况下,JSON.stringify()
和JSON.parse()
已经够用了。在看红宝书的时候,感觉打开了新世界的大门。下面就来探秘一下灵活的JSON使用方法。
JSON.stringify()
的几个作用
JSON.stringify()
方法将一个JavaScript对象转换成JSON字符串。
当属性值为undefined
、函数时会跳过这个属性,转换的JSON字符串中不存在跳过的属性。
过滤结果
第二个参数是数组
如果第二个参数是一个数组,那么JSON.stringify()
得到的结果只包含该数组中列出的对象属性。 得到的结果也会按数组中对象的属性顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022 };
const jsonText = JSON.stringify(person, ['age', 'name'])
console.log(jsonText)
|
第二个参数是函数
如果第二个参数是一个函数,那么该函数接收两个参数: 属性名(key)和属性值(value)。返回的值就是得到的对象字符串,该属性的值。
如果函数返回的值不是对象,那么得到的结果就是返回的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022 };
const jsonText = JSON.stringify(person, (key, value) => { console.log('key: ', key) console.log('value: ', value)
})
console.log(jsonText)
|
那么,怎么得到最初的结果呢?
答案很简单,可以直接返回value
值就行了。
那么如果想修改某一个属性值,就只需要增加条件,根据条件返回就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022 };
const jsonText = JSON.stringify(person, (key, value) => { switch (key) { case 'name': return '赤蓝紫'; case 'hobbies': return value.join(',') default: return value }
})
console.log(jsonText)
|
如果想要得到的结果中过滤掉某个属性,那么只需要当key
等于该属性时,返回undefined
即可
1 2 3 4 5 6 7 8
| switch (key) { case 'name': return '赤蓝紫'; case 'hobbies': return undefined default: return value }
|
假如我们想要全部属性都变成ccc
,是不是只需要返回ccc
就行了呢?
这个上面已经说过了,如果只是返回ccc
的话,那么最后的结果只是一个ccc
字符串,而不是JSON对象字符串
。
如果想要把全部属性都变成ccc
,除了返回ccc
外,还需要当key
等于空串时,需要返回value
。
因为只有当key
等于空串时返回一个对象,才会继续去转换该对象的属性为字符串。否则,就直接拿到值就返回了。(注意: 如果返回的是函数,得到的结果是undefined
)
1 2 3 4 5 6 7
| if (key === '') { return value } else { return 'ccc' }
|
接下来玩点有意思的,我们可以在key
等于空串时,返回另一个对象,这样就能做到狸猫换太子了。
1 2 3 4 5 6 7 8 9 10 11 12
| if (key === '') { return { test: { test1: 1, test2: 2 } } } else { return value }
|
字符串缩进
上面我们通过JSON.stringify()
得到的JSON对象字符串
是没有格式的,看起来有点杂乱无章。这时候就轮到我们的第三个参数出场了,第三个参数用来控制缩进字符。
如果第三个参数是数值,表示缩进的空格数。最大缩进值为10,大于10的值会自动设置为10。
1 2 3 4 5 6 7 8 9 10 11 12 13
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022 };
const jsonText = JSON.stringify(person, null, 4) console.log(jsonText)
|
第三个参数也可以是字符串,这样子就会使用这个字符串来缩进。
比如:
1
| const jsonText = JSON.stringify(person, null, '--')
|
toJSON()方法
如果对象的值是函数,那么我们使用JSON.stringify()
时,就会忽略掉这个属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022, tt: function () {
} };
const jsonText = JSON.stringify(person, null, 4) console.log(jsonText)
|
但是,当名称是toJSON
时,就不太一样了,如果调用toJSON
能获取到实际的值,那么JSON.stringify()
会得到toJSON
返回的实际值。当然,这个实际值也是会受到第二个参数、第三个参数的影响的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let person = { name: "clz", age: 22, hobbies: [ "Animate", "Music", 'FrontEnd' ], nowTime: 2022, toJSON: function () { return { name: 'haha', age: 22, job: { type: 'Coder', } } } };
const jsonText = JSON.stringify(person, ['name', 'age'], 4) console.log(jsonText)
|
JSON.parse()
JSON.parse()
方法可以把JSON字符串转换为JSON对象
1 2 3 4 5
| let person = '{"name": "clz"}'
const jsonObj = JSON.parse(person)
console.log(jsonObj)
|
JSON字符串属性必须使用双引号,单引号会导致语法错误
1 2 3 4 5
| let person = "{'name': 'clz'}"
const jsonObj = JSON.parse(person) console.log(jsonObj)
|
如果属性值是字符串,也需要使用双引号
,否则会语法错误。如果属性值不是字符串,那么就不需要引号。
1 2 3 4 5 6
| let person = `{"name": "clz"}` person = '{"age": 21}'
person = `{"name": 'clz'}` const jsonObj = JSON.parse(person) console.log(jsonObj)
|
值不能是undefined
和函数,会报错,加上双引号后,不会报错,但值也变成字符串类型了。
1 2 3 4 5
| let person = `{"name": "undefined"}`
const jsonObj = JSON.parse(person) console.log(jsonObj)
|
第二个参数
JSON.parse()
可以接收第二个参数(函数), 用来修改解析生成的原始值。每个键值对都会调用一次,有点点像数组的map
函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| let person = { name: "clz", age: 21, nowTime: 2022, };
const jsonStr = JSON.stringify(person)
const jsonObj = JSON.parse(jsonStr, (key, value) => { if (key === 'name') { return '赤蓝紫' } else if (key === 'age') { return undefined }
return value })
console.log(typeof jsonObj) console.log(jsonObj)
|
用处: 比如可以把日期字符串转换为Date
对象
1 2 3 4 5 6 7 8 9 10 11 12
| let person = { name: "clz", age: 21, nowTime: new Date(2022, 11, 31) };
const jsonStr = JSON.stringify(person)
const jsonObj = JSON.parse(jsonStr)
console.log(jsonObj.nowTime) console.log(typeof jsonObj.nowTime)
|
如果不进行任何操作,上面的Date对象
转换成字符串,再转换成对象,会变成日期字符串了。而且,日期还减了一天。
如果我们想要还原成Date对象
,并得到正确的时间,可以使用第二个参数来实现,只需要用该日期字符串实例化一个日期对象,再返回就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| let person = { name: "clz", age: 21, nowTime: new Date(2022, 11, 31) };
const jsonStr = JSON.stringify(person)
const jsonObj = JSON.parse(jsonStr, (key, value) => { if (key === 'nowTime') { return new Date(value) }
return value })
console.log(jsonObj.nowTime) console.log(typeof jsonObj.nowTime)
|