你不知道的JSON
引言
在我们与后端进行接口数据定义时,绝大部分的数据格式都是 JSON。有些经常需要进行属性扩展的对象数据也通常是使用 JSON字符串 来进行数据库存储的。由此可见,熟练掌握 JSON的使用就非常的重要,不过,相信大家都对JSON不陌生,所以这篇文章也会给大家来点”不一样的“
我们熟知的JSON
JSON: JavaScript Object Notation
定义
JSON是一种语法,用来 序列化对象、数组、数值、字符串、布尔值和 null
。 它基于 JavaScript 语法,但与之不同:JavaScript 不是 JSON,JSON 也不是 JavaScript。
使用
JSON
对象包含两个方法:用于解析 JavaScript Object Notation(JSON)的 parse()
方法,以及将对象/值 转换为 JSON 字符串的 stringify()
方法。除了这两个方法,JSON 这个对象本身并没有其他作用,也不能被调用或者作为构造函数调用。
所以我们只需要关注JSON.parse()
、JSON.stringify()
这两个方法。
JSON.stringify()
:参数为 javascript 对象/值,返回 JSON 字符串,可以理解为 序列化。JSON.parse()
:参数为 JSON字符串,返回 javascript 对象/值,可以理解为 反序列化。
看起来很简单对吧,到这里为止都是我们所熟悉的JSON,但是你真的了解JSON吗,比如,JSON.stringify(undefined)
你知道返回值是什么吗?
JSON.stringify
JSON.stringify(value[, replacer [, space]])
value:将要序列化成 一个 JSON 字符串的值。
replacer 可选:
如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
space 可选:
指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
JSON.parse
JSON.parse(text[, reviver])
text:要被解析成 JavaScript 值的字符串
reviver 可选:
转换器,如果传入该参数 (函数),可以用来修改解析生成的原始值,调用时机在 parse 函数返回之前。
掌握JSON对我们开发出健壮性更强的代码也是必不可少的
你不知道的JSON
上面的题的答案是:JSON.stringify(undefined)
的返回值为undefined
,why?
当你问出为什么的时候,你该好好看看上面JSON的定义
JSON是一种语法,用来 序列化 对象、数组、数值、字符串、布尔值和
null
重点看斜体加粗内容,对于基本类型(number、string、boolean、undefined、null、symbol、BigInt),只能序列化number、string、boolean、null,对于引用类型只能序列化对象和数组
JSON.stringify
/*
* JavaScript 各种数据类型的 序列化
*/
JSON.stringify(undefined) // undefined 注意:不是 'undefined'
JSON.stringify(null) // 'null'
// Boolean类型
JSON.stringify(true) // 'true'
JSON.stringify(false) // 'false'
// 常用数字类型(注意:最后都会输出十进制)
JSON.stringify(0) // '0'
JSON.stringify(012) // '10'
JSON.stringify(0x12) // '18'
JSON.stringify(1e2) // '100'
JSON.stringify(Infinity) // null
JSON.stringify(NaN) // null
JSON.stringify(112n) // TypeError: Do not know how to serialize a BigInt
// 字符串类型
JSON.stringify('12') // '"12"' 注意:不是 "12"
// Symbol 类型
JSON.stringify(Symbol(12)) // undefined 注意:不是 'undefined'
// 对象类型
JSON.stringify({ a: '12', b: 12}) // '{"a":"12","b":12}'
// 数组类型
JSON.stringify([]) // '[]'
JSON.stringify([1, '2', { a: '12'}]) // '[1,"2",{"a":"12"}]'
JSON.stringify([undefined]) // [null]
// Set/Map
JSON.stringify(new Set([1,2])) // '{}'
JSON.stringify(new Map().set('a', 1)) // '{}'
序列化引用类型时还需要注意:
- 在非数组对象的属性值中:undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略;在数组中:被转换成 null;函数被单独转换时,会返回 undefined:JSON.stringify(function foo(){}) // undefined
- 对包含循环引用的对象(对象之间相互引用,形成无限循环),会抛出错误。(所以使用JSON进行深拷贝时需要注意)
- 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
JSON.parse
/*
* JavaScript 反序列化
* 方法签名: JSON.parse(text[, reviver])
*/
JSON.parse('undefined') // Uncaught SyntaxError: "undefined" is not valid JSON
JSON.parse('null') // null
// Boolean类型
JSON.parse('true') // true
JSON.parse('false') // false
// 常用数字类型
JSON.parse('0') // 0
JSON.parse('12') // 12
JSON.parse('012') // Uncaught SyntaxError: Unexpected number in JSON at position 1
JSON.parse('0x12') // Uncaught SyntaxError: Unexpected non-whitespace character after JSON at position 1
JSON.parse('1e2') // 100
// 字符串类型
JSON.parse('') // Uncaught SyntaxError: Unexpected end of JSON input
JSON.parse('""') // ''
JSON.parse('"0"') // '0'
JSON.parse('"012"') // '012'
// Symbol
JSON.parse(Symbol(1)) //TypeError: Cannot convert a Symbol value to a string
// 对象类型
JSON.parse('{}') // {}
JSON.parse('{"a":"12","b":12}') // { a: '12', b: 12}
// 数组类型
JSON.parse('[]') // []
JSON.parse('[1,"2",{"a":"12"}]') // [1, '2', { a: '12'}]
使用JSON.parse时需要注意的是:待转换JSON字符串不允许使用逗号结尾,如:
JSON.parse("[1, 2, 3, ]");
JSON.parse('{"a" : 1, }');
遇到该格式时会报错
当然这点我们在使用编辑器时会自动给我们提示:
转载自:https://juejin.cn/post/7265156603066368034