JSON格式
json格式是js语言中用于数据交换的文本格式,比起XML格式,JSON格式有以下特点:
1、书写简单、一目了然
2、js原生支持其语法,不需要另外的解析器。JSON格式目前已经被纳入各大网站通用的数据交换格式标准。
JSON对象必须是一个值,可以是数组或者对象,或者是原始类型的值。但是必须是一个值,不能是多个。
以下是JSON对象的格式要求: 1、复杂数据类型必须是数组或者是对象,不能是函数、日期对象、正则对象等
2、原始类型的值只能是以下几种:1、字符串 2、数字 3、布尔值 4、null 不能使用undefined、NaN
3、字符串只能是双引号
4、对象的键名只能放在双引号内
5、数组或者对象最后一个成员不能加双引号
示例:
["name","123"]
[{"name":"qiuyanxi"},{"age":18}]
JSON对象静态方法
JSON.stringify
JSON.stringify将一个值转化为可以被JSON格式识别的字符串。并且这个值可以被JSON.parse方法还原。
SON.stringify('abc') // ""abc""
JSON.stringify(1) // "1"
JSON.stringify({name:1,age:2}) //"{"name":1,"age":2}"
JSON.stringify([1,2,3,4,5,'6']) //"[1,2,3,4,5,"6"]"
JSON.stringify(false) //"false"
值得注意的是,如果参数为字符串,那么会被转成"\"xxx\""的形式
JSON.stringify('abc') ==="\"abc\"" //true
可以这样理解:由于所有单引号都会被转成双引号,那么内层双引号就需要一个转义符让js引擎知道,这是一个字符串。
JSON.stringify('false') === "\"false\""
JSON.stringify(false) //"false"
要是没有内层的双引号,那么上面的代码可能会被解析成布尔值
如果对象的属性是undefined、函数等,那么就会被JSON.stringify过滤
JSON.stringify({name:function(){},age:undefined}) // "{}"
如果数组的属性值是undefined、函数等则会被解析成null
JSON.stringify([undefined,function(){}]) // "[null,null]"
如果是正则对象,则被转成空对象
JSON.stringify(/foo/) // "{}"
同时,JSON会忽略一些不可遍历的对象属性。
第二个参数
JSON.stringify共接收三个参数,第二个参数可以是数组,也可以是函数。
当是数组时,可以指定需要转成字符串的属性。
JSON.stringify([{name:"qiu",age:11},{name:"yan",halo:1}],["name","halo"])
//结果:
// "[{"name":"qiu"},{"name":"yan","halo":1}]"
要注意的是,这个功能只对对象有效。
JSON.stringify(["name","age"],["name"])
// "["name","age"]" ---无效
如果第二个参数是函数,可以用来处理stringify的返回值。
JSON.stringify({'name':'qiu',age:10},function(key,value){
if(key ==="age"){
value=value*2
}
return value
})
// "{"name":"qiu","age":20}"
上面代码中,如果键名是age,则让值乘以2。
这个函数会递归处理所有的键
JSON.stringify({a:{b:{c:{d:1}}}},function(key,value){
console.log(key+':'+value)
return value
})
// :[object Object] 第一次
// a:[object Object] 第二次
// b:[object Object] 第三次
// c:[object Object] 第四次
// d:1 第五次
//"{"a":{"b":{"c":{"d":1}}}}" 返回值
上面的函数一共执行5次,第一次的键名为空,键值为整个对象{a:{b:{c:{d:1}}}},第二次键名为a,键值为{b:{c:{d:1}}},第三次键名为b,键值为{c:{d:1}},第四次键名为c,键值为{d:1},第五次键名为d,键值为1。
最后返回"{"a":{"b":{"c":{"d":1}}}}"
这个递归函数在执行时,每次处理的对象,都是上一次返回的值。
let a={name:"123"}
JSON.stringify(a,function(key,value){
debugger
if(key ==='name'){
return undefined
}
return value
})
//"{}"
我们debugger上面的代码测试一下,会发现第一次进入时,键名为空,值为整个对象{name:"123"}
这时候不会进入判断,会直接返回一个value,继续执行。
当第二次进入时,键名变成name,键值变成"123"
发现key是
name,然后直接return 返回一个undefined。
如果处理函数返回的是undefined或者没有返回值,那么该属性会被忽略。
所以上述代码返回的是一个空对象
第三个参数
JSON.stringify可以接收第三个参数,用于增加返回的JSON字符串的可读性。例如,参数为数字时,则表示每个属性前面加多少个空格。如果参数是字符串,那么在每行前面就会加上这个字符串。
let a={name:"qiu",age:1}
JSON.stringify(a,null,3)
"{
"name": "qiu",
"age": 2
*/
JSON.stringify(a,null,"-1")
"{
-1"name": "qiu",
-1"age": 2
}"
参数的toJSON方法
如果参数对象有自定义的toJSON方法,那么就会以这个方法的返回值作为参数 作为对比,这里先放正常的参数
let a={name:"qiuyanxi",age:11}
JSON.stringify(a)
// "{"name":"qiuyanxi","age":11}"
let a={
name:"qiuyanxi",
age:11,
toJSON(){
return this.age+this["name"]
}
}
JSON.stringify(a)
// {"11qiuyanxi"}
上面第二个代码以toJSON的返回值作为参数返回JSON格式的字符串
JSON.parse
这个方法是和JSON.stringify()对应的,将转为JSON字符串的值给转回对应的值。
JSON.parse("null") // null
JSON.parse("\"2\"") // "2"
跟JSON.stringify方法一样,JSON.parse可以接收第二个参数函数
let a='{"name":2,"age":2}'
JSON.parse(a,function(key,value){
if(key ==="age"){
return value*2
}
return value
})
// {name:2,age:2}
上面代码中,当key为“age”时,将值*2返回