json

本文深入解析JSON数据格式的语法特点,包括其与JS对象的区别、数据类型支持、序列化与反序列化方法,以及如何利用额外参数进行数据过滤与美化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON是一种轻量级的数据交换格式,相对于xml,它体积小,使用非常简便,受到了开发人员们的热烈欢迎,是目前主流的一种格式。

json中可以保存简单值,如字符串,数值,布尔值,unll,也可以保存对象以及数组,但不支持undefined和函数。

var json = {
	"name" : "json",
	"age" : 1,
	"arr" : [1,{},3]
}

以上就是json的语法格式,与js的对象与数组字面量很相似,但需要注意的是,json规定对象的键名必须加上双引号,并且,字符串值也必须加上双引号,否则会报错。
对象的键值可以是简单值,也可以是复杂数据类型,通过复杂数据类型之间的相互嵌套,json就可以表示出足够满足我们需求的数据结构。
json数据结构的最外层不一定是一个对象,当然也可以是一个数组,通常情况下,最外层的数据类型就是这两种。

JSON对象

JSON对象有两个方法,分别是stringify方法,用来将js对象转换为json字符串,和parse方法,用来将json格式的字符串转换为原生JavaScript值。

var json = {
	name : 'json',
	boolean : false,
	null : null,
	number : 1,
	arr : [1,2,3]
}

JSON.stringify(json) //{"name":"json","boolean":false,"null":null,"number":1,"arr":[1,2,3]}

在js对象被序列化为json格式的字符串结果中,属性都被加上了双引号,原本用单引号表示的字符串也被替换成了双引号,序列化的结果中也不包含空格与缩进。

var json = {
	name : undefined,
	fun : function () {}
}

JSON.stringify(json) // {}

根据转换后的结果可以看到,在对于不支持的数据类型时,undefined和函数不会被序列化,而是直接被忽略,结果序列化的结果只是一个空对象。

使用parse方法,则可以将传入的json字符串转换为相应的原生js值。

var obj = JSON.parse('{"name" : "json","boolean" : false,"null" : null,"number" : 1,"arr" : [1,2,3]}');
obj.name //'json'

需要注意的是,虽然parse方法接受的json字符串是一样的,但每次序列化后的js对象都是独立的。

var json = '{"name" : "json","boolean" : false,"null" : null,"number" : 1,"arr" : [1,2,3]}';

var obj1 = JSON.parse(json);
console.log(obj1.name) //json

var obj2 = JSON.parse(json);
console.log(obj2.name) //json

console.log(obj2 === obj1) //false

通过这样的特性,可以实现对象的拷贝:

var obj = {
	name : 'obj',
	age : 1,
	arr : [1,2,3]
}

var objclone = JSON.parse(JSON.stringify(obj));

obj.arr === objclone.arr //false

当然这样方法的缺陷显而易见,当js对象被序列化成json字符串时,如果其中包含如undefined或函数这样的数据类型时,将会被忽略。

stringify方法的额外参数

stringify方法还可以接受第二和第三个参数,第二个参数是一个过滤器,可以是一个数组或者函数。

var json = {
	name : 'json',
	boolean : false,
	null : null,
	number : 1,
	arr : [1,2,3]
}

JSON.stringify(json,["name","boolean"]) //{"name":"json","boolean":false}

通过传入一个数组,那么该方法会只将数组中指定的键名放入序列化结果中。

如果是一个函数,那么每个键和值会被传入回调函数中,函数的返回值会把相应的键值替换掉,如果返回undefined,那么该属性会被忽略,该键值对不会出现在序列化结果中。

var obj = {
    "username":"hello world",
    "age":20,
    "height":"185cm",
    "address":"Shanghai"
}

JSON.stringify(obj, function(key, val){
    switch(key){
        case "username":
            return "javascript";
        case "age":
            return 10;
        case "height":
            return undefined;   //height属性会被忽略
        default:
            return val;
    }
});

//结果:{"username":"javascript","age":10,"address":"Shanghai"}

JavaScript对象在序列化之后不会保留空格与缩进,但使用第三个参数可以用来控制缩进

var jsonText = JSON.stringify(json,null,3)

以上代码表示在每个级别上缩进3个空格

结果:

{
  "name": "json",
  "boolean": false,
  "null": null,
  "number": 1,
  "arr": [
    1,
    2,
    3
  ]
}

如果给定参数是一个字符串,则这个字符串将被用做缩进字符。

var jsonText = JSON.stringify(json,null,'__')

结果:

{
__"name": "json",
__"boolean": false,
__"null": null,
__"number": 1,
__"arr": [
____1,
____2,
____3
__]
}

toJSON方法

当stringify方法接受的对象中存在toJSON方法时,会将方法中返回的值进行序列化处理。

var json = {
	"name" : 'json',
	"boolean" : false,
	"null" : null,
	"number" : 1,
	"arr" : [1,2,3],
	toJSON : function () {
		return {name : this.name,age:this.number};
	}
}

JSON.stringify(json) //{"name":"json","age":1}

toJSON方法中返回的值将会被传入过滤器函数中,因此可以在过滤器函数中对toJSON方法的返回值进行处理:

var json = {
	"name" : 'json',
	"boolean" : false,
	"null" : null,
	"number" : 1,
	"arr" : [1,2,3],
	toJSON : function () {
		return {name : this.name,age:this.number};
	}
}

JSON.stringify(json,function (key,value) {
	switch(key){
       case "name":
           return "JSON";
       case "age":
           return 10;
       default:
           return value;
   	}
})

结果:

{"name":"JSON","age":10}

parse方法的第二个参数

parse方法的第二个参数和stringify方法的过滤器函数相似,该函数将在每个键值对上调用,并接受当前的键名与键值为参数,如果该方法返回undefined,那么当前键值将不会出现在序列化后的结果中,如果返回的是其他值,则该值会用作当前键的键值。

var json = {
	"name" : 'json',
	"boolean" : false,
	"null" : null,
	"number" : 1,
	"arr" : [1,2,3],
	"date" : new Date(2011,11,1)
}

var jsonText = JSON.stringify(json) 

结果:

{"name":"json","boolean":false,"null":null,"number":1,"arr":[1,2,3],"date":"2011-11-30T16:00:00.000Z"}

上面的例子中,json对象中的Date对象被序列化后成了普通的json字符串,下面在使用parse方法对其进行序列化为JavaScript对象的时候,使用了处理函数,将date对象进行还原。

var jsonObj = JSON.parse(jsonText,function (key,value) {

	if (key === 'date') {
		return new Date(value);
	}else {
		return value;
	}
})

jsonObj.date.getFullYear() //2011
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值