JSON格式,(简写JavaScript Object Notation),是一种用于数据交换的文本格式,书写简单。

基于JavaScript原生语法,能够序列化对象、数组、数值、字符串、布尔值和 null。

在ES5中,增加了一个JSON对象,专门用来处理JSON格式的数据。

JSON是一个对象,但只有两个方法:parsestringify,不能作为构造函数,也无属性。

  1. typeof JSON === 'object'

JSON.parse

JSON.parse() 用来解析JSON字符串,得到对应的JavaScript值或对象。

  1. JSON.parse('{}') // {}
  2. JSON.parse('true') // true
  3. JSON.parse('null') // null

JSON.parse 语法

  1. JSON.parse(text[, reviver])
  • text:要被解析成的字符串。

    如果传入数字则会转换成十进制数字输出。

    如果传入布尔值则直接输出。

    如果传入null则输出null。

    不支持其他类型的值,否则报错。
  • reviver: 可选,转换器, 可以用来修改解析生成的原始值。

返回值: JavaScript对象/值, 对应给定JSON文本的对象/值。

reviver 参数

reviver函数,用于转换处理解析到的JavaScript值,处理完后返回最终的结果。

转换过程:

  • 解析的值本身和它可能包含的所有属性,按照一定遍历顺序分别调用reviver函数,属性名和值作为参数两个参数 keyvalue 传入。

    遍历顺序:按照层级,从内往外遍历,最终到达最顶层,则是解析值本身。
  • reviver返回undefined,则删除该对象,如果返回了其他值,则该值会成为当前属性的新值。
  • 当遍历到最顶层时,因为没有属性了,参数key是空字符串'',参数value则是当前解析值。

对于reviver函数的两个参数 keyvalue,不同的数据类型:

  • 基本值类型数据(string、number、boolean)和null,以及空对象{}和空数组[]

    则key是空字符串,value是对应解析值。

    因为已经是最顶层,并没有别的属性。
  • Object对象:

    则key和value都存在,与属性名和值各自对应。

    最顶层会返回一个参数key为空的值。
  • 数组:

    key对应数组索引,value对应元素值。

    最顶层会返回一个参数key为空的值。

基本类型的转换:

  1. JSON.parse('5', function (key, value) {
  2. console.log(`key:${key}, value:${value}`)
  3. })
  4. // key:, value:5
  5. JSON.parse('null', function (key, value) {
  6. console.log(`key:${key}, value:${value}`)
  7. })
  8. // key:, value:null
  9. JSON.parse('{}', function (key, value) {
  10. console.log(`key:${key}, value:`, value)
  11. })
  12. // key:, value:{}

Object对象和数组:

  1. JSON.parse('[1, 2]', function (key, value) {
  2. console.log(`key:${key}, value:`, value)
  3. })
  4. // key:0, value: 1
  5. // key:1, value: 2
  6. // key:, value: (2) [empty × 2]
  7. JSON.parse('{ "user": "张三", "info": { "age": 25, "sex": 1 } }', function (key, value) {
  8. console.log(`key:${key}, value::`, value)
  9. })
  10. // key:user, value:: 张三
  11. // key:age, value:: 25
  12. // key:sex, value:: 1
  13. // key:info, value:: {}
  14. // key:, value:: {}

数据处理:

  1. JSON.parse('[1, 2]', function (key, value) {
  2. if(key === '') {
  3. return value
  4. }
  5. return value + 3
  6. })
  7. // [4, 5]

JSON.parse 特性

在解析JSON字符串的时候,需要注意到JSON格式的一些规范,不然就容易报错。

JSON数据对值的类型和格式,都有严格的规定,具体的规则如下:

  1. 该方法使用字符串类型JSON格式数据。

    该方法也支持数字、布尔值和null三个类型的值,转换出对应的字面值。

    不支持其他类型。
  1. JSON.parse('"中国"')
  2. // '中国'
  3. JSON.parse(null) // null
  4. JSON.parse(111.) // 111
  5. JSON.parse(0x12) // 18
  6. JSON.parse(true) // true
  7. JSON.parse([])
  8. // Uncaught SyntaxError: Unexpected end of JSON input
  1. 字符串必须使用双引号,不能使用单引号。
  1. JSON.parse('"String"')
  2. // 'String'
  3. JSON.parse('\'String\'')
  4. // Uncaught SyntaxError: Unexpected token ' in JSON at position 0
  1. 只支持十进制的字符串,但小数点后必须跟上数字。
  1. JSON.parse('111') // 111
  2. JSON.parse('0x12')
  3. // Uncaught SyntaxError: Unexpected token x in JSON at position 1
  4. JSON.parse('111.232') // 111.232
  5. JSON.parse('111.')
  6. // Uncaught SyntaxError: Unexpected end of JSON input
  1. 不能使用undefined、Symbol和BigInt,数字也不支持NaN、Infinity和-Infinity,都会报错。
  1. JSON.parse(undefined)
  2. // Uncaught SyntaxError: Unexpected token u in JSON at position 0
  3. JSON.parse(Symbol())
  4. // Uncaught TypeError: Cannot convert a Symbol value to a string
  5. JSON.parse('12n')
  6. // Uncaught SyntaxError: Unexpected token n in JSON at position 2
  1. 复合类型,只能是:[]{} 这样的字面量。

    不能使用对象构造函数,因为会当作执行语句,不支持。

    不能使用Object和Array,也不能是函数、RegExp对象、Date对象、Error对象等。
  1. JSON.parse('[]')
  2. // []
  3. JSON.parse('Object()')
  4. // Uncaught SyntaxError: Unexpected token O in JSON at position 0
  1. 对象的属性名必须使用双引号。
  1. JSON.parse('{"key": 1 }')
  2. // {key: 1}
  3. JSON.parse('{key: 1 }')
  4. // Uncaught SyntaxError: Unexpected token k in JSON at position 1
  1. 数组或对象最后一个成员的后面,不能加逗号。
  1. JSON.parse('[1, 2, 3, 4, ]')
  2. // VM2771:1 Uncaught SyntaxError: Unexpected token ] in JSON at position 13
  3. JSON.parse('{"key" : 1, }')
  4. // VM2779:1 Uncaught SyntaxError: Unexpected token } in JSON at position 12
  1. 支持unicode转义。
  1. JSON.parse('{"\u0066":333}')
  2. // {f: 333}
  1. 部分控制字符、转义字符不支持,如'\n'、'\t'等。
  1. JSON.parse('"\n"')
  2. // Uncaught SyntaxError: Unexpected token

解析的其他方法

将json字符串转成json对象(js对象值),还可以使用其他方法,但是非安全代码。

  1. const str = '{"name":"json","age":18}'
  2. const json = JSON.parse(str)
  3. const json = eval("(" + str + ")")
  4. const json = (new Function("return " + str))()

JSON.stringify

JSON.stringify() 将一个JavaScript对象或值转换为JSON格式字符串。

JSON.stringify 语法

  1. JSON.stringify(value[, replacer [, space]])
  • value:将要序列化成 一个 JSON 字符串的JavaScript对象或值。
  • replacer 可选,用于处理将要序列化的值。
  • space 可选,指定缩进用的空白字符串,用于美化输出。

返回值: 一个表示给定值的JSON格式字符串。

replacer参数

replacer 参数可以以下三种情况:

  1. 如果是null、undefined或其他类型,则被忽略,不做处理;
  1. JSON.stringify({key: 'json'}, null, null) // '{"key":"json"}'
  2. JSON.stringify({key: 'json'}, true) // '{"key":"json"}'
  1. 如果是一个数组,则只有包含在这个数组中的属性名,才会最终被序列化到结果字符串中;

    只对对象的属性有效,对数组无效。
  1. const obj = {
  2. json: 'JSON',
  3. parse: 'PARSE',
  4. stringify: 'STRINGIFY'
  5. }
  6. JSON.stringify(obj, ['parse', 'stringify'])
  7. // '{"parse":"PARSE","stringify":"STRINGIFY"}'
  1. 如果是一个函数,被序列化的值的每个属性都会经过该函数的转换和处理;

处理过程:

  • 函数有两个参数,属性名(key)和属性值(value),都会被序列化;
  • 第一次调用时,key为空字符串,value则为需要序列化的整个对象;
  • 第二次处理时,会把第一次的的结果传过来,后续的每一次的处理都将接收上一次处理的结果;
  • 后面,将依次处理每个属性名和属性值,完成后返回。
  1. JSON.stringify({ json: 1, stringify: { val: 'rr'} }, (key, value) => {
  2. console.log(`key:${key},value:`, value)
  3. return value
  4. })
  5. // key:,value: {json: 1, stringify: {…}}
  6. // key:json,value: 1
  7. // key:stringify,value: {val: 'rr'}
  8. // key:val,value: rr
  9. // '{"json":1,"stringify":{"val":"rr"}}'

value的类型处理:

  • 如果返回基本类型字符串、数字、布尔值、null,则直接被添加到序列化后的JSON字符串中;
  • 如果返回其他对象,则会在后续依次序列化该对象的属性,如果是函数则不作处理;
  • 如果返回或undefined,则不会输出该属性。
  • 序列化数组时,如果value返回undefined或者一个函数,将会被null取代。
  1. JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  2. if (typeof value === 'number') {
  3. return 'ss'
  4. }
  5. return value
  6. })
  7. // '{"json":"ss","stringify":"rr"}'
  8. JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  9. if (typeof value === 'number') {
  10. value = undefined
  11. }
  12. return value
  13. })
  14. // '{"stringify":"rr"}'

下面示例,是返回对象值时的处理:

  1. JSON.stringify({ json: 1, stringify: 'rr' }, (key, value) => {
  2. if (typeof value === 'object') { // 第一次返回整个对象时,类型是object
  3. return { parse: 'dd' }
  4. }
  5. return value
  6. })
  7. '{"parse":"dd"}'

space 参数

space 参数用来控制结果字符串里面的间距,美化输出。可以输入的值有以下三种情况:

  • 如果是一个数字, 序列化时,每一层级比上一层级多缩进对应数字值的空格,范围在 1 - 10,即最小1个最大10个空格;
  • 如果是一个字符串,序列化时,该字符串会添加在每行前面,每一层级比上一层级多缩进该字符串,最多是个字符,超过则截取字符串;
  • 如果是null、undefined或其他类型,则被忽略,不做处理。
  1. JSON.stringify({key: 'json'}, null, 2)
  2. // '{\n "key": "json"\n}'
  3. JSON.stringify({key: 'json', list: { str: 'str' } }, null, '|-')
  4. // '{\n|-"key": "json",\n|-"list": {\n|-|-"str": "str"\n|-}\n}'
  5. JSON.stringify({key: 'json'}, null, null)
  6. // '{"key":"json"}'

JSON.stringify 特性

  1. 基本类型值字符串、数字、布尔值,以及String、Boolean、Number对象值,都会转成原始值字符串输出。
  1. JSON.stringify(333) // '333'
  2. JSON.stringify(true) // 'true'
  3. JSON.stringify(new String('333')) //'"333"'
  4. JSON.stringify(Boolean(true)) // 'true'
  1. 基本类型的字符串,转换结果会带双引号。

    因为在还原时,双引号会让JavaScript知道是字符串,而不是变量。
  1. JSON.stringify('json') === 'json' // false
  2. JSON.stringify('json') === '"json"' // true
  1. undefined、函数、symbol以及XML对象:
  • 出现在Object对象中时,会被忽略;
  • 出现在数组中时,会被序列化成null;
  • 单独出现时,会返回undefined。
  1. JSON.stringify(Symbol()) // undefined
  2. JSON.stringify([Symbol(), Math.abs, undefined]) // '[null,null,null]'
  3. JSON.stringify({ [Symbol()]: Math.abs, key: undefined }) // '{}'
  1. NaN、Infinity和-Infinity等值,还有null,都会被序列化成null。
  1. JSON.stringify(null) // 'null'
  2. JSON.stringify(NaN) // 'null'
  1. Object对象,以及Map/Set/WeakMap/WeakSet等复合类型对象,序列化时会忽略对象的不可遍历属性。
  1. const obj = {}
  2. Object.defineProperties(obj, {
  3. 'json': { value: 'JSON', enumerable: true },
  4. 'stringify': { value: 'STRINGIFY', enumerable: false }
  5. })
  6. JSON.stringify(obj)
  7. // '{"json":"JSON"}'
  1. 以symbol为属性名的属性将被忽略。
  1. JSON.stringify({[Symbol()]: 333}) // '{}'
  1. 除了数组,其他对象的属性在序列化时,顺序可能会乱。
  1. const a = { '1': 911, 'r': 822, '11': 9922}
  2. JSON.stringify(a)
  3. // '{"1":911,"11":9922,"r":822}'
  1. 转换的对象如果定义了 toJSON() 方法,则该方法的返回值就是转换对象的序列化结果。

    该过程会忽略其他属性。
  1. const a = { key: 'json' }
  2. a.toJSON = () => 'JSON'
  3. JSON.stringify(a)
  4. // '"JSON"'
  1. RegExp对象、Error对象都会序列化为空对象字符串。
  1. JSON.stringify(/\d/) // "{}"
  2. JSON.stringify(new Error()) // "{}"

想要序列化相应对象,需要设置实现toJSON方法才行。

  1. RegExp.prototype.toJSON = RegExp.prototype.toString
  2. JSON.stringify(/\d/) // '"/\\\\d/"'
  1. Date对象已经定义了toJSON(),并将其转换为string字符串,因此可被序列化。

    Date.toISOString()
  1. JSON.stringify(new Date())
  2. // '"2021-12-31T02:24:05.477Z"'
  1. 循环引用的对象执行此方法,会抛出错误。

    对象之间相互引用,形成无限循环。
  1. const a = {}
  2. a.key = a
  3. JSON.stringify(a)
  4. // Uncaught TypeError: Converting circular structure to JSON
  1. 转换BigInt类型的值会抛出TypeError错误。

    BigInt值不能JSON序列化
  1. JSON.stringify(12n)
  2. // Uncaught TypeError: Do not know how to serialize a BigInt
  1. 更好的支持unicode转义符
  1. const a = {'\u0066': 333}
  2. JSON.stringify(a)
  3. // '{"f":333}'

JSON.parse 和 JSON.stringify 详解的更多相关文章

  1. JSON.parse和JSON.stringify 参数详解

    JSON.parse和JSON.stringify这两个浏览器自带(IE6/7除外)的方法平常我们经常用到,但是一般都只是用到了他们的第一个参数,比如字符串转对象:JSON.parse('{}')   ...

  2. JSON.parse()与JSON.stringify()和eval()使用方法详解

    在和后端对接口的时候,遇到了一个问题 就是series里面数据变量进行拼接的时候,data数据里面全部是数值int类型的 但是因为某些需求需要让他进行某个数据之前的数据都为空 我试过用空字符串和und ...

  3. JSON.parse() 和 JSON.stringify()

    JSON.parse()和JSON.stringify()   1.parse 用于从一个字符串中解析出json 对象.例如 var str='{"name":"cpf& ...

  4. arguments.callee 调用函数自身用法----JSON.parse()和JSON.stringify()前端js数据转换json格式

    arguments.callee 调用函数自身用法 arguments.callee 在哪一个函数中运行,它就代表哪个函数. 一般用在匿名函数中. 在匿名函数中有时会需要自己调用自己,但是由于是匿名函 ...

  5. 有关javascript中的JSON.parse和JSON.stringify的使用一二

    有没有想过,当我们的大后台只是扮演一个数据库的角色,json在前后台的数据交换中扮演极其重要的角色时,作为依托node的前端开发,其实相当多的时间都是在处理数据,准确地说就是在处理逻辑和数据(这周实习 ...

  6. Jquery里面种的 JSON.parse() 与JSON.stringify() 的区别

    JSON.parse()与JSON.stringify()的区别   JSON.parse()[从一个字符串中解析出json对象] Demo: //定义一个字符串 var data='{"N ...

  7. JSON.parse()和JSON.stringify()的解析与用途

    JSON.parse()和JSON.stringify()的解析与用途 1.parse用于从一个字符串中解析出json对象 如: var str = '{"name":" ...

  8. JSON.parse() 和 JSON.stringify() 的区别

    JSON.parse()与JSON.stringify()的区别   JSON.parse()[从一个字符串中解析出json对象] //定义一个字符串 var data='{"name&qu ...

  9. 秒懂JSON.parse()与JSON.stringify()的区别

    在网站开发中,Json是最为常见的一种数据交互手段.在使用过程中,常会遇到Json字段串和对象之间进行转换.很多朋友对于JSON.parse() 和JSON.stringify() 的区别,下面为大家 ...

随机推荐

  1. 移动开发之h5学习大纲

    移动开发学习形式:授课.自学 1.html5 css3 htm5shiv.js response.js 2.流式布局 自适应布局 盒模型 弹性盒模型 响应式布局3.iscroll swiper boo ...

  2. 强化学习实战 | 表格型Q-Learning玩井字棋(二)

    在 强化学习实战 | 表格型Q-Learning玩井字棋(一)中,我们构建了以Game() 和 Agent() 类为基础的框架,本篇我们要让agent不断对弈,维护Q表格,提升棋力.那么我们先来盘算一 ...

  3. 安全相关,CSRF

    先说下CSRF的定义 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF ...

  4. Oracle异常处理——ORA-01502:索引或这类索引的分区处于不可用状态

    Oracle异常处理--ORA-01502:索引或这类索引的分区处于不可用状态参考自:https://www.cnblogs.com/lijiaman/p/9277149.html 1.原因分析经过查 ...

  5. tomcat 8 内存优化

    在Linux环境下设置Tomcat JVM,在/opt/tomcat/bin/catalina.sh文件中找到"# ----- Execute The Requested Command&q ...

  6. 十二. Go并发编程--sync/errGroup

    一.序 这一篇算是并发编程的一个补充,起因是当前有个项目,大概の 需求是,根据kafka的分区(partition)数,创建同等数量的 消费者( goroutine)从不同的分区中消费者消费数据,但是 ...

  7. spring切面-单线程简单权限判定

    spring切面简单模拟用户权限判定 需求: 游客:仅注册用户 用户:修改,注册 管理员:删除,查询,修改,注册 1,文件配置 导包 src下创建applicationContext.xml文件配置如 ...

  8. Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  9. 自定义函数(Power Query 之 M 语言)

    数据源: 任意工作簿 目标: 使用自定义函数实现将数据源导入Power Query编辑器 操作过程: PowerQuery编辑器>主页>新建源>其他源>空查询 编辑栏内写入公式 ...

  10. 最新超详细VMware下CentOS系统安装

    一.了解CentOS系统 CentOS是免费的.开源的.可以重新分发的开源操作系统,CentOS(Community Enterprise Operating System,中文意思是社区企业操作系统 ...