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的对象字面量有三点不同:

  1. JSON中没有变量
  2. JSON中键名必须用双引号包裹
  3. 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()方法时,序列化的顺序如下:

  1. 如果有toJSON()方法并且能返回有效值,则先调用该方法。
  2. 如果提供了函数过滤器,则应用函数过滤器。
  3. 对第二步返回的值进行序列化。
  4. 如果提供了第三个参数,执行格式化。

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
posted @ 2021-09-29 11:32  wmui  阅读(309)  评论(0编辑  收藏  举报