JSON
: JavaScript Object Notation,是一种用于数据交换的文本格式.
- 复合类型的值只能是数组或对象,不能是
、函数
、正则表达式对象
。日期对象
- 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和
(不能使用null
,NaN
,Infinity
和-Infinity
)。undefined
- 字符串必须使用双引号表示,不能使用单引号。
- 对象的键名必须放在双引号里面。
- 数组或对象最后一个成员的后面,不能加逗号。
JSON对象的两个静态方法 - JSON.stringify()
- JSON.stringify():用于将一个值转为JSON字符串(该字符串符合JSON格式,并且可以被JSON.parse()方法还原)
let obj = {
name: "中小余",
age: 18,
gender: "女",
like:undefined, // undefined也不会被转换
say: function() { // 不能是函数,所以不会转换
return "hello word.";
}
};
JSON.stringify(obj); // '{"name":"中小余","age":18,"gender":"女"}'
* 对象的属性是undefined、函数或XML对象,该属性会被JSON.stringify()过滤
JSON.stringify(false) // "false"
JSON.stringify('false') // "\"false\"" 字符串false为了跟布尔值false区分 转换后会在前后加 "\"
* 数组的成员是undefined、函数或XML对象,则这些值会被转换成null
let arr = [undefined,function(){}];
JSON.stringify(arr); //'[null,null]'
* 正则会被转换为空对象
JSON.stringify(/xx/);//'{}'
* 它还会忽略对象的不可遍历的属性(enumerable属性为false时)
let obj = {};
Object.defineProperties(obj,{
'name':{
value:1,
enumerable:true
},
'age':{
value:18,
enumerable:false
}
})
JSON.stringify(obj); // '{"name":1}' age被忽略了
- JSON.stringify() 可以有第二个参数:
/* JSON.stringify()方法还可以接受一个数组,作为第二个参数,指定参数对象的哪些属性需要转成字符串。
*/
* 相当于白名单,但只对对象的属性有效,对数组无效。
let obj = {
name:'中小余',
age:18,
gender:'女',
likeWord:'一勤天下无难事'
};
let selectedProperty = ['name','likeWord']; // 白名单
JSON.stringify(obj,selectedProperty);
// '{"name":"中小余","likeWord":"一勤天下无难事"}' 数组里没有的都不会被转化
* 第二个参数还可以是一个函数,用来更改JSON.stringify()的返回值
let obj = {
num1:10,
num2:2
};
function fun(key,value){
console.log(key);
console.log(value);
if(typeof value === 'number'){
value = 2 * value;
}
return value;
}
JSON.stringify(obj,fun); // '{"num1":20,"num2":4}' 递归处理函数所有的键,每一次处理的对象,都是前一次返回的值;如果处理函数返回undefined或没有返回值,则该属性会被忽略。
- 第三个参数:用于增加返回的 JSON 字符串的可读性。
let obj = {
name:'中小余',
age:18,
gender:'女',
likeWord:'一勤天下无难事'
};
JSON.stringify(obj,null,'\t');// \t在每个属性前面添加一个制表符,然后分行显
/*
`{
"name": "中小余",
"age": 18,
"gender": "女",
"likeWord": "一勤天下无难事"
}`
*/
JSON.stringify(obj,null,2);// 在每个属性前面添加的空格数(最多不超过10个)。
/*`{
"name": "中小余",
"age": 18,
"gender": "女",
"likeWord": "一勤天下无难事"
}`*/
toJson()
如果参数对象有自定义的
toJSON()
方法,那么
JSON.stringify()
会使用这个方法的返回值作为参数,而忽略原对象的其他属性。
let obj = {
name: "中小余",
age: 18,
gender: "女",
like:'一勤天下无难事',
say: function() {
return "hello word.";
},
toJSON: function(){
return this.name + this.like
}
};
JSON.stringify(obj); // '"中小余一勤天下无难事"'
// JSON.stringify()发现参数对象有toJSON()方法,就直接使用这个方法的返回值作为参数,而忽略原对象的其他参数。
- Date对象就有一个自己的toJSON()方法
let now = new Date();
now.toJSON(); //'2021-04-07T14:00:34.444Z'
JSON.stringify(now);// '"2021-04-07T14:00:34.445Z"'
toJSON()
方法的一个应用是,将正则对象自动转为字符串。因为
JSON.stringify()
默认不能转换正则对象,但是设置了
toJSON()
方法以后,就可以转换正则对象了。
let obj = {
reg:/xxx/
}
// 不设置toJSON方法时
JSON.stringify(obj); //'{"reg":{}}'
// 设置toJSON方法
RegExp.prototype.toJSON = RegExp.prototype.toString;
JSON.stringify(obj); // '{"reg":"/xxx/"}'
JSON.parse():方法用于将 JSON 字符串转换成对应的值
var yuInfo = JSON.parse('{"name": "中小余"}');
yuInfo.name; // '中小余'
// 如果传入的字符串不是有效的 JSON 格式,JSON.parse()方法将报错。
- 为了处理解析错误,可以将JSON.parse()方法放在try...catch代码块中
try{
JSON.parse('zhongxiaoyu');
} catch(e){
console.log('error');
}
// 'error'
- JSON.parse()方法可以接受一个处理函数,作为第二个参数,用法与JSON.stringify()方法类似
function f(key, value) {
if (key === 'a') {
return value + 10;
}
return value;
}
JSON.parse('{"a": 1, "b": 2}', f); // { a: 11, b: 2 }