2006年,Douglas Crockford 在国际互联网工程组制定了 JavaScript对象简谱(JSON,JavaScript Object Notation)标准,即 RFC 4627。但实际上,JSON早在2001年就开始使用了。JSON 是 JavaScript 的严格子集,利用JavaScript 中的几种模式来表示结构化数据。
理解JSON最关键了一点是要把它当成一种数据格式,而不是编程语言。JSON 不属于 JavaScript,它们只是有相同的语法而已。JSON 也不是只能在 JavaScript 中使用,它是一种通用数据格式。很多语言都有解析和序列化 JSON 的内置功能。
JSON 语法支持表示三种类型的值。
最简单的 JSON 可以是一个数值。例如,下面是这个数值是有效的 JSON:
6
这个 JSON 表示数值 5。类似地,下面这个字符串也是有效的JSON:
"Hello world!"
注:JSON 字符串必须使用 双引号(单引号会导致语法错误)。布尔值和 null 本身也是有效的JSON 值。
对象使用与 JavaScript 对象的字面量略为不同的方式表示。一下是JavaScript 中对象字面量:
let user = {
name: "sa",
age: 18,
phone: "1983472343"
}
但在 JSON 中的对象必须使用双引号把属性名包围起来。如下代码与前面代码是相同的:
let object = {
"name": "sa",
"age": 18,
"phone": "1983472343"
};
而用 JSON 表示相同的对象的语法是:
{
"name": "sa",
"age": 18,
"phone": "1983472343"
}
注:与 JavaScript 对象字面量相比,JSON 主要有两处不同。首先,没有变量声明(JSON 中没有变量)。其次,最后没有分号(不需要,因为不是 JavaScript 语法)。同样,用引号将属性名包围起来才是有效的 JSON。属性值可以是简单值或复杂数据类型值,后者可以在对象中在嵌入对象。
JSON的第二种复杂数据类型是数组。数组在 JSON 中使用 JavaScript 的数组字面量形式来表示。
如下是一个 JavaScript 数组:
let values = ['sa',18,true];
在 JSON 中同样可以使用类似的语法表示相同的数组:
["sa",18,true]
注意:这里没有变量,也没有分号。数组可以和对象混合使用,用来表示更加复杂的数据结构。
[
{
"name":"sa",
"age":18,
"address":"上海",
"detail":[
{
"birthday":"2000年11月20号",
"interesting":"game"
},
{
"height":180,
"weight":160,
"isAdult":true
}
]
},
{
"name":"sb",
"age":16,
"address":"上海",
"detail":[
{
"birthday":"2000年11月20号",
"interesting":"game"
},
{
"height":170,
"weight":120,
"isAdult":false
}
]
}
]
JSON 的迅速流行并不仅仅因为其语法与 JavaScript 类似,很大程度上还因为 JSON 可以直接被解析成可用的Javascript 对象。JSON 对象有两个方法 :stringify() 和 parse()。简单情况下,这两个方法分别可以将 JavaScript 序列化为 JSON 字符串,以及将 JSON 解析成原生的 JavaScript 值。
这是一个将 JavaScript 数据序列化成 JSON 字符串的方法。默认情况下,JSON.stringify() 会输出一个不包含空格或缩进的 JSON 字符串。
let person = {
name: '张三',
age: 20,
family: {
father: '李思',
mather: '王琦'
}
}
console.log(JSON.stringify(person))
// 输出结果如下:
// {"name":"张三","age":20,"family":{"father":"李思","mather":"王琦"}}
let person = {
name: '张三',
age: 20,
money: Infinity,
eat (){
console.log('对象方法!')
},
address: NaN,
girlfriend: undefined
}
console.log(JSON.stringify(person))
// 输出:{"name":"张三","age":20,"money":null,"address":null}
如上例子中:NaN 和 Infinity 属性值会自动转换为 null,而对象里面的方法和 undifined 属性也自动省略了。
JSON.stringify() 这个方法可以传入第二个参数,起到过滤对象属性的作用。这个参数可以是数组也可以是一个函数。当我们传入一个函数时,我们可以接受两个参数,一个属性名(key)和属性值(value)。我们可以对传入的 key 对应的属性值,然后执行我们想要的操作。
js中 person 代码中的属性
let person = {
name: '张三',
age: 20,
money: '200w',
friend: {
name: 'gg',
age: 28,
birthday: '2000.1.2'
}
}
执行如下语句,将 person 中的 name、age、friend过滤出来
console.log(JSON.stringify(person,['name','age','friend']))
输出结果如下:
{“name”:“张三”,“age”:20,“friend”:{“name”:“gg”,“age”:28}}
js 对象同上是 person
console.log(JSON.stringify(person,(key,value) => {
switch (key) { // 遍历属性名和属性值,return 出去的就是经过处理后的值,当然这里只是简单演示
case 'money':
return '3000w';
case 'name':
return 'sa';
case 'birthday':
return '2000年1月2号';
default:
return value;
}
}))
打印结果:
{“name”:“sa”,“age”:20,“money”:“3000w”,“friend”:{“name”:“sa”,“age”:28,“birthday”:“2000年1月2号”}}
如上打印结果可知,当对象里面包含对象时,同名的属性值会一同修改,而最终转换成 JSON 字符串的属性值就是我们return 出去的值。
JSON.stringify() 方法中,我们还可以传入第三个参数用于控制缩进和空格。在这个参数是数值(当参数大于10时会自动设置为10)时,表示每一级缩进空格数。也可以传入字符。
js中 person 对象
let person = {
name: '张三',
age: 20,
money: '200w',
friend: {
name: 'gg',
age: 28,
birthday: '2000.1.2'
}
}
console.log(JSON.stringify(person,null,4))// 每一级缩进4个空格
打印结果如下(我并没有对打印结果进行JSON格式化):
{
"name": "张三",
"age": 20,
"money": "200w",
"friend": {
"name": "gg",
"age": 28,
"birthday": "2000.1.2"
}
}
JSON.parse() 是解析 JSON 数据的一种方法,将 JSON 串解析成 JavaScript 中对象结构的 API。
当然该方法也可以额外接收一个函数,使用方法和JSON.stringify() 相同。同样接收属性名(key)和属性值(value)。这个函数也称为还原函数。
如下演示一个案例。
let jsonStr = '{"name":"张三","age":20,"money":"200w","newDate":"2022年"}'
let userOne = null;
userOne = JSON.parse(jsonStr,(key,value) => {
if (key === 'newDate'){
return Date.now() // 如果key是newDate则返回一个当前时间戳
}else {
return value
}
})
console.log(userOne)
打印结果如下:
{name: ‘张三’, age: 20, money: ‘200w’, newDate: 1672752998876}