JS内置对象-JSON对象
JSON(JavaScript Object Notation)全称JavaScript对象表示法,是一种数据交换的文本格式,用于读取结构化数据。
语法规则
JSON的语法可以表示三种类型值:简单值、对象、数组。
简单值
JSON中的简单值可以是字符串、数值、布尔值、null。
字符串必须使用双引号。数值必须是十进制,并且不能是NaN和Infinity。JSON不支持JS中的特殊值undefined。
// 正确
"hello"
3
true
null
// 错误
'hello'
0xa
NaN
Infinity
undefined
对象
对象表示的一组有序键值对。键值对中的值可以是简单值也可以是复杂值。
JSON和JS的对象字面量有三点不同:
- JSON中没有变量
- JSON中键名必须用双引号包裹
- JSON末尾没有分号
// 正确
{
"name": "wmui",
"age": 20,
"job": {
"name": "Front-End",
"location": "Hangzhou"
}
}
// 错误
{
name: "wmui",
'age': 10,
"date": new Date(),
"sayName": function(){
return this.name
}
}
数组
数组表示一组值的列表。数组中元素值可以是简单值也可以是复杂值。
[
"wang",
"li",
"zhao"
]
注意: 数组或对象最后一个成员的后面,不能加逗号
方法
JSON对象有两个方法:stringify()用于把JS值序列化成JSON字符串,parse()方法用于把JSON字符串解析成JS值。
stringify()
console.log(JSON.stringify('wmui')) // "wmui"
console.log(JSON.stringify(3)) // "3"
console.log(JSON.stringify(true)) // "false"
console.log(JSON.stringify(null)) // "null"
console.log(JSON.stringify(['li','wang'])) // ["li","wang"]
console.log(JSON.stringify({name: 'wmui'})) // {"name":"wmui"}
正则表达式和Math对象会被转换成空对象的字符串形式。
console.log(JSON.stringify(/foo/)) // {}
console.log(JSON.stringify(Math)) // {}
日期对象和包装对象会被转化成字符串
console.log(JSON.stringify(new String('wmui'))); // "wmui"
console.log(JSON.stringify(new Number(3))); // "3"
console.log(JSON.stringify(new Boolean(true))); // "true"
console.log(JSON.stringify(new Date())); // "2018-05-29T04:55:36.718Z"
对象中如果出现undefined或函数,会被忽略掉。
数组中如果出现undefined或函数,会被转换成null。
console.log(JSON.stringify({
a: undefined,
b: function(){},
c: [undefined,function(){}]
})); // {"c":[null,null]}
对象或数组中出现NaN或Infinity,会被转换成null。
console.log(JSON.stringify({
a: NaN,
b: Infinity,
c: [NaN,Infinity]
}));
//{"a":null,"b":null,"c":[null,null]}
对象中不可遍历的属性会被忽略掉
var obj = {};
Object.defineProperties(obj, {
a: {
value: 1,
enumerable: true
},
b: {
value: 2,
enumerable: false
}
});
console.log(JSON.stringify(obj)); // {"a":1}
stringify()参数
JSON.stringify()可以另外接收两个参数:第一个参数表示过滤器,可以是数组或函数;第二个参数表示JSON字符串缩进。
【过滤器】
var obj = {
name:'wmui',
age: 20,
sex: 'boy'
};
console.log(JSON.stringify(obj,['name','age'])); // {"name":"wmui","age":20}
当过滤器是函数时,函数接收两个参数:第一个是键名,第二个是键值。
var obj = {
a: 10,
b: 12,
c: 5
};
var ret = JSON.stringify(obj,function(key,value){
if(typeof value === "number"){
value = value + '元'
}
return value;
})
console.log(ret) // {"a":"10元","b":"12元","c":"5元"}
过滤器函数会递归处理所有的键。对于非键值对儿结构的值,键名可以是空字符串。
var obj = {
a: 10,
b: 12,
c: 5
};
var ret = JSON.stringify(obj,function(key,value){
console.log(key+':'+value)
return value;
})
// :[object Object]
// a:10
// b:12
// c:5
如果函数返回了undefined或没有返回值,对应的属性会被忽略
var obj = {
a: 10,
b: 12,
c: 5
};
var ret = JSON.stringify(obj,function(key,value){
if(value > 10) {
return undefined;
}
return value;
})
console.log(ret); // {"a":10,"c":5}
【缩进】
缩进值可以是数字(数字小于等于10),表示每个属性前面添加的空格数。也可以是字符串,字符串会添加到每行前面。
console.log(JSON.stringify({a:1,b:2,c:3},null,2))
/*
{
"a": 1,
"b": 2,
"c": 3
}
*/
console.log(JSON.stringify({a:1,b:2,c:3},null,'-'))
/*
{
-"a": 1,
-"b": 2,
-"c": 3
}
*/
toJSON()
当使用JSON.stringify()无法满足对象序列化的需求时,可以调用对象的toJSON()的方法,该方法返回自身的JSON数据格式。
var obj = {
name:'wmui',
toJSON: function(){
return this.name
}
};
console.log(JSON.stringify({a:obj})) // {"a":"wmui"}
Date对象部署了自己的toJSON()方法,会自动把Date对象转换成日期字符串。
console.log(JSON.stringify(new Date())); // "2018-05-29T06:57:52.829Z"
可以为正则表达式部署toJSON()方法,把正则对象转换成字符串。
RegExp.prototype.toJSON =RegExp.prototype.toString;
console.log(JSON.stringify(/foo/)) // "/foo/"
toJSON()方法常作为函数过滤器的补充,当把一个对象传给JSON.stringify()方法时,序列化的顺序如下:
- 如果有toJSON()方法并且能返回有效值,则先调用该方法。
- 如果提供了函数过滤器,则应用函数过滤器。
- 对第二步返回的值进行序列化。
- 如果提供了第三个参数,执行格式化。
parse()
JSON.parse()用于把JSON字符串解析成对应的JS值。
console.log(JSON.parse('"wmui"')) // wmui
console.log(JSON.parse('3')) // 3
console.log(JSON.parse('true')) // true
console.log(JSON.parse('null')) // null
console.log(JSON.parse('["li","wang"]')) // ["li","wang"]
console.log(JSON.parse('{"name":"wmui"}')) // {name:"wmui"}
JSON.parse()可以另外接受一个函数作为参数,这个函数叫做还原函数。还原函数接收键名和键值两个参数。
如果返回值是undefined或没有返回值,对应的属性会被忽略。
var ret = JSON.parse('{"a":5,"b":12,"c":10}',function(key,value){
if(value < 10) {
return undefined
}
return value;
})
console.log(ret); // {b: 12, c: 10}
把日期字符串转换成Date对象时,经常用到还原函数
var book = {
author: 'wmui',
date: '2018-05-29T06:57:52.829Z'
}
var newBook = JSON.parse(JSON.stringify(book), function(key,value){
if(key === 'date') {
return new Date(value)
}
return value;
})
console.log(newBook.date.getFullYear()); // 2018