JSON(回顾)

本文介绍了JSON,它是JavaScript对象标记法,用于序列化多种数据类型。详细讲解了JSON的两个方法:stringify将JS对象或值转为JSON字符串,parse用于解析JSON字符串。还说明了方法参数的作用、存在的特征、异常处理,最后提及JSON实现的三种方式。

JSON是什么

JSON,全称是 JavaScript Object Notation,即 JavaScript对象标记法。
JSON 是一种语法,用来序列化对象、数组、数值、字符串、布尔值和 null,基于JS,但是JSON并不是JS的子集
JSON字符串:一种传输数据的格式,本质是字符串
注意:JSON字符串属性名称必须是双引号括起来的字符串;最后一个属性后不能有逗号

JSON的方法

  • JSON.stringify()
  • JSON.parse()

JSON.stringify(value,replacer,space)

定义:将一个JS对象或值转换为JSON字符串,返回JSON字符串
参数1:要被转换的对象或值
参数2:数组或函数,对序列化的每个属性进行处理,可选
参数3:指定缩进用的字符串,用于美化输出,数字代表多少个空格(1-10),字符串代表该字符串作为缩进,可选,默认没有空格

JSON.stringify([undefined,function test() {},Symbol(""),{ a: 1 },]);
//'[null,null,null,{"a":1}]'
replacer参数

定义:数组或函数格式,对序列化的每个属性进行处理,可选
数组格式 包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中

JSON.stringify({ a: 1, b: 2 }, ["a"]);//'{"a":1}'
函数格式

每个属性都会经过该函数的转换和处理,会按照最顶层属性开始往里,最终达到里层
注意:当遍历到顶层时,传入的形参1会是空字符串 ‘’,形参2是被修改完成的对象,所以得返回该对象

var res = JSON.stringify({ a: 1, b: 2 }, function (prop, v) {
  if (prop === "") {
    return v;
  }
  console.log(prop, v);
  return v + 1;
});
console.log(res); //'{"a":2,"b":3}'
space参数

定义:用来控制结果字符串里面的间距,数字代表多少个空格(1-10),字符串代表该字符串作为缩进,可选,默认没有空格
常用 \t 换行符

// 使用'\t'制表符
JSON.stringify({ a: 1, b: 2 }, null, "\t");
{
	"a": 1,
	"b": 2
}

存在的几个特征

  1. Boolean | Number | String 类型自动会转换为对应原始值
// Boolean对象
let temp =JSON.stringify(new Boolean(1))
console.log(typeof temp) // string
console.log(typeof JSON.parse(temp)) // boolean
// Number对象
let temp =JSON.stringify(new Number(1))
console.log(typeof temp)// string
console.log(typeof JSON.parse(temp))// number
// String对象
let temp =JSON.stringify(new String(1))
console.log(typeof temp)// string
console.log(typeof JSON.parse(temp))// string
  1. undefined、任意函数、symbol,这三种类型在非数组对象中会被忽略, 在数组中转换成null,在单个值时转换为 undefined

数组对象中 :>> undefined、任意函数、symbol,这三种类型转换为 “null”

// 数组中
let test = () => {};
let arr = [new String(1),test,Symbol("1"),undefined,null];
let temp = JSON.stringify(arr)
console.log(temp);// '["1",null,null,null,null]'
console.log(JSON.parse(temp));// [1,null,null,null,null]

非数组对象中 :>> undefined、任意函数、symbol,这三种类型会被忽略

// 非数组对象中 
let obj = {
  a: new Number(1),
  b: ()=>{},
  c: Symbol(1),
  d:undefined,
  e:null
}
let temp =JSON.stringify(obj)
console.log(temp);// '{"a":1,"e":null}'
console.log(JSON.parse(temp));// { a: 1, e: null }

单个值时:>> undefined、任意函数、symbol,这三种类型转换为 undefined

// 单个值时,当前因为parse需要json格式对象,这样是没意义的
let temp =JSON.stringify(Symbol(1))
console.log(temp)// 'undefined'
let temp1 =JSON.stringify(()=>1)
console.log(temp1) // 'undefined'
  1. 不可枚举属性会被忽略,数组中不会被忽略
let obj = {
  a: new Number(1),
}
Object.defineProperty(obj, "b", {
  value: '1',
  configurable: false, // 可配置性,默认为false
  enumerable: false, // 可枚举性,默认为false
  writable: false, // 可重写性,默认为false
});
let temp =JSON.stringify(obj)
console.log(temp)// '{ a: 1 }'
console.log(JSON.parse(temp))// { a: 1 }
  1. 如果对象属性通过 get 方式返回对象本身,即循环引用,该属性会被忽略
let obj = {
  a: new Number(1),
  b:'1'
}
Object.defineProperty(obj, "b", {
  get(v){
    return v
  }
});
let temp =JSON.stringify(obj)
console.log(temp)// '{ a: 1 }'
console.log(JSON.parse(temp))// { a: 1 }

封装stringify

class L {
	stringify(tar) {// JSON.stringify
    // 1.Boolean | Number | String 类型自动会转换为对应原始值
    // 2.undefined、任意函数、symbol,这三种类型在非数组对象中会被忽略,在数组中转换成null,在单个值时转换为 undefined
    // 3.不可枚举属性会被忽略,数组中不会被忽略
    // 4.如果对象属性通过 get 方式返回对象本身,即循环引用,该属性会被忽略
    var type = typeof tar;
    if (type !== "object") {
      if (/undefined|function|symbol/.test(type)) {
        return String(undefined);
      }
      return String(tar);
    } else if (tar === null) {
      return "null";
    } else if (tar.constructor === Array) {// 数组
      let json = [];
      for (var i = 0; i < tar.length; i++) {
        var v = tar[i];
        var type1 = typeof v;
        if (/undefined|function|symbol/.test(type1) || v === null) {
          v = "null";
        } else if (/string/.test(type1) || v instanceof String) {
          v = '"' + v + '"';
          console.log(v);
        } else {
          v = this.stringify(v);
        }
        json.push(String(v));
      }
      return "[" + json.join() + "]";
    } else {// 非数组对象
      var json = [];
      if (tar instanceof Number || tar instanceof Boolean || tar instanceof String) {
        return String(tar);
      }
      for (var k in tar) {
        var v = tar[k];
        var type2 = typeof v;
        if (/undefined|function|symbol/.test(type2)) {
          continue;
        } else if (v === null) {
          v = "null";
        } else if (/string/.test(type2) || tar instanceof String) {
          v = '"' + v + '"';
        } else {
          v = this.stringify(v);
        }
        json.push('"' + k + '":' + String(v));
      }
      return "{" + json.join() + "}";
    }
  }
}

JSON.parse(text, reviver)

定义:用来解析JSON字符串,返回油字符串描述的对象或值
参数1:被解析的JSON字符串
参数2:转换器,用来修改生成的对象,可选

var res = JSON.parse('{"a":1,"b":2}', function (prop, v) {
  if (prop === "") {
    console.log(v,'顶层')
    return v;
  }
  console.log(prop);
  console.log(this);
  return v +1;
});
/*
a
{ a: 1, b: 2 }
b
{ a: 2, b: 2 }
{ a: 2, b: 3 } 顶层
*/
console.log(res);// {a: 2, b: 3}
reviver参数

定义:用来修改生成的对象,会按照最里层属性开始往外,最终达到顶层
形参1:当前对象属性名
形参2:当前对象属性值
注意:当遍历到顶层时,传入的形参1会是空字符串 ‘’,形参2是被修改完成的对象,所以得返回该对象

JSON.parse('{"p": 5}', function (k, v) {
  if(k === '') return v;     // 如果到了最顶层,则直接返回属性值,这个是最后指向的
  return v * 2;              // 否则将属性值变为原来的 2 倍
});                          // { p: 10 }
JSON的异常

开发过程中,常常遇到这个错误,这是JSON数据格式不对,得找JSON.parse的参数,找寻具体错误
在这里插入图片描述

封装 parse

参考 梁少峰:JSON实现的三种方式

方式1:使用 eval,存在xss危险(跨站脚本攻击)

class L {
  parse(tar) {//存在xss漏洞(跨站脚本攻击)
    return eval("(" + tar + ")");
  }
}

方式2:使用Function

class L {
  parse2(tar){//使用Function
    return (new Function('return' + tar))()
  }
}

方式3:递归,请参考上文

这里推荐下 查看正则的工具

<think> 首先,用户的问题是关于JSON.toJSON的,但我需要回顾提供的引用。引用中提到了JSON.stringify()、toJSON方法、JSON.parse、JSON.toJSONString()、Gson.toJson()等,但没有直接提到JSON.toJSON。 从引用[1]:它讨论了JSON.stringify()和toJSON方法在JavaScript中的使用。它显示,如果对象有一个toJSON方法,JSON.stringify()会调用它来序列化对象。 引用[2]:比较了JSON.toJSONString()(来自阿里巴巴的FastJSON)和Gson.toJson()(来自谷歌的Gson),两者都用于Java对象到JSON字符串的转换。 引用[3]:提供了在Java中使用Gson.toJson()的示例。 引用[4]:讨论了JavaScript中的JSON方法和toJSON。 引用[5]:显示了如何在JavaScript中使用toJSON方法配合JSON.stringify()来过滤属性。 用户的问题是:“我想了解JSON.toJSON的相关信息,可能是使用方法、功能用途等 请问JSON.toJSON的使用方法和相关介绍” 关键是JSON.toJSON在引用中没有直接出现。在引用[2]中,提到了JSON.toJSONString(),这是FastJSON中的一个方法。但没有JSON.toJSON。 在JavaScript中,toJSON是对象的一个方法,而不是JSON对象本身的一个属性。JSON是一个全局对象,其方法包括stringify和parse,但不包括toJSON。toJSON是对象可以定义以实现自定义序列化的方法。 在Java上下文中,像FastJSON和Gson这样的库有toJson方法,例如Gson.toJson()或FastJSONJSON.toJSONString()。 用户可能混淆了术语。他们可能指的是在JavaScript中使用toJSON方法,或者在Java中使用像toJson这样的方法。 回顾用户的问题:“JSON.toJSON”,这可能是一个错误;可能是“toJSON”方法或像FastJSON这样的库中的JSON.toJSONString()。 在引用[2]中,它说:“JSON.toJSONString()和Gson.toJson()方法比较。”所以JSON.toJSONString()是阿里巴巴FastJSON库的一部分。 类似地,在引用[5]中,它展示了在JavaScript中使用toJSON。 为了准确回答,我应该澄清: - 在JavaScript中,toJSON是一个方法,对象可以实现该方法,以便在使用JSON.stringify()进行序列化时进行自定义。 - 在Java中,像Gson或FastJSON这样的库有序列化方法,例如Gson.toJson()JSON.toJSONString()。 用户指定了“JSON.toJSON”,所以可能指的是FastJSONJSON.toJSONString(),因为在引用[2]中它被写作JSON.toJSONString(),但用户说“JSON.toJSON”,这可能是一个缩略语或错误。 我应该参考引用并提供一个清晰的解释。 系统指令: - 所有行内数学表达式使用 $...$。 - 独立公式使用 $$...$$ 并单独成段。 - 使用中文回答。 - 生成相关问题。 - 在引用的段落末尾添加引用标识,例如[^1]。 - 回答结构清晰,逐步解决问题。 由于没有数学表达式,我可以跳过LaTeX部分。 结构回答: 1. 解释什么是JSON.toJSON或澄清术语。 2. 基于引用描述用法。 3. 提供示例。 4. 结束时有相关问题。 首先,澄清:在标准JSON中,没有JSON.toJSON方法。在JavaScript中,有JSON.stringify(),它可以使用对象的toJSON方法。在Java中,有诸如FastJSONJSON.toJSONString()之类的库方法。 从引用[2]:JSON.toJSONString()是阿里巴巴FastJSON库的一部分。 类似地,引用[3]讨论了Gson.toJson()。 所以,我认为用户指的是类似的东西。 在回答中: - 解释在JavaScript中,toJSON是一个自定义序列化的方法。 - 在Java中,JSON.toJSONString()是FastJSON的一个方法。 - 提供示例。 使用引用: - 引用[1]用于JavaScript中的toJSON:当对象有toJSON方法时,JSON.stringify()使用它。 - 引用[5]显示了一个示例。 - 引用[2]用于JSON.toJSONString()在Java中的使用。 - 引用[3]用于Gson.toJson()。 对于“JSON.toJSON”,可能是一个错误,所以我应该涵盖可能的解释。 回答结构: 1. 介绍JSON序列化。 2. 解释在JavaScript中的toJSON方法。 3. 解释在Java中的类似方法如JSON.toJSONString()。 4. 提供使用方法和示例。 5. 添加引用。 6. 生成相关问题。 最终输出应以“相关问题”结束。 使用中文。 </think>### JSON.toJSON 的相关介绍和使用方法 根据您的查询,“JSON.toJSON”可能是一个术语上的混淆或简写。在标准 JSON 规范中,没有直接称为“JSON.toJSON”的内置方法。但基于提供的引用,这很可能指的是两种常见场景: - **在 JavaScript 中**:toJSON 是对象的一个自定义方法,用于在序列化时控制 JSON 输出(通常与 JSON.stringify() 配合使用)。 - **在 Java 中**:JSON.toJSONString() 是阿里巴巴 FastJSON 库提供的方法,用于将 Java 对象转换为 JSON 字符串(引用中提到了类似方法)。 下面我将逐步解释这些概念、功能用途和使用方法,确保内容基于可靠引用并结构清晰。回答中将包括 JavaScript 和 Java 的示例,以覆盖不同上下文。 --- ### 1. **什么是 toJSON 方法?功能用途介绍** toJSON 方法允许对象在序列化为 JSON 字符串时自定义输出内容。它通常用于: - **过滤不必要属性**:例如,移除敏感或临时字段(如 flag 或调试信息)。 - **格式化数据结构**:将复杂对象转换为更简洁的 JSON 表示。 - **兼容不同库**:在 Java 中,类似方法(如 JSON.toJSONString() 或 Gson.toJson()) 用于对象序列化。 在 JavaScript 中,toJSON 不是 JSON 对象的直接方法,而是对象自身实现的属性。当调用 JSON.stringify() 时,它会自动检测并调用对象的 toJSON 方法(如果存在),优先使用其返回值进行序列化(引用[1]和[5])。在 Java 中,JSON.toJSONString() 是 FastJSON 库的静态方法,用于高效序列化[^2]。 关键优点: - **灵活性**:自定义序列化逻辑,避免输出冗余数据。 - **效率**:减少 JSON 字符串大小,提升网络传输性能。 - **跨平台兼容**:JavaScript 和 Java 库(如 Gson)都支持类似机制。 --- ### 2. **在 JavaScript 中的使用方法和示例** 在 JavaScript 中,toJSON 是对象的一个可选方法。您需要在对象上定义它,然后通过 JSON.stringify() 触发序列化。 **基本语法:** ```javascript const obj = { // ...属性定义 toJSON() { // 自定义序列化逻辑:返回一个简化对象或值 return simplifiedObject; } }; JSON.stringify(obj); // 输出序列化后的 JSON 字符串 ``` **示例代码(基于引用[5]):** 假设有一个用户对象,您想移除 `flag` 属性: ```javascript const user = { name: '张三', age: 23, flag: true, // 不需要序列化的属性 toJSON() { delete this.flag; // 移除 flag return this; // 返回简化后的对象 } }; console.log(JSON.stringify(user)); // 输出: {"name":"张三","age":23} ``` 在这个例子中: - JSON.stringify() 检测到 toJSON 方法,并调用它。 - toJSON 方法删除了 `flag` 属性,返回简化对象。 - 最终输出不包含 `flag`,只序列化 `name` 和 `age`[^5]。 **另一个示例(基于引用[1]):** 自定义输出格式: ```javascript const user = { firstName: 'zzz', lastName: 'ran', age: 23, toJSON() { return { fullName: `${this.firstName} ${this.lastName}` }; // 返回新对象 } }; console.log(JSON.stringify(user)); // 输出: {"fullName":"zzz ran"} ``` 这里,toJSON 方法将对象转换为一个只包含 `fullName` 的新对象,序列化后输出更简洁[^1]。 **使用注意事项:** - toJSON 方法必须返回一个可序列化的值(如对象、数组或基本类型)。 - 如果未定义 toJSONJSON.stringify() 会使用默认序列化规则。 - 确保在 toJSON 中避免循环引用,否则会导致错误(引用[4])。 --- ### 3. **在 Java 中的使用方法和示例** 在 Java 中,没有原生 toJSON 方法,但库如 FastJSON 或 Gson 提供了类似功能。引用中提到的 JSON.toJSONString() 是阿里巴巴 FastJSON 库的方法,用于序列化 Java 对象。 **基本语法(FastJSON):** ```java import com.alibaba.fastjson.JSON; // 定义一个 Java 对象 public class User { private String name; private int age; // getter 和 setter 方法 } User user = new User(); user.setName("小牧"); user.setAge(23); String jsonString = JSON.toJSONString(user); // 序列化为 JSON 字符串 System.out.println(jsonString); // 输出: {"age":23,"name":"小牧"} ``` **示例代码(基于引用[2]和[3]):** 使用 FastJSONJSON.toJSONString(): ```java import com.alibaba.fastjson.JSON; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("name", "小牧"); map.put("age", "23"); map.put("hobby", "游戏"); String json = JSON.toJSONString(map); // 序列化 Map 对象 System.out.println(json); // 输出: {"hobby":"游戏","name":"小牧","age":"23"} } } ``` 在这个例子中,JSON.toJSONString() 将 Java Map 对象转换为 JSON 字符串[^2]。 **与 Gson 库的比较(基于引用[2]和[3]):** Gson 提供 Gson.toJson() 方法,用法类似: ```java import com.google.gson.Gson; import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("name", "小牧"); map.put("age", "23"); Gson gson = new Gson(); String json = gson.toJson(map); // 使用 Gson 序列化 System.out.println(json); // 输出: {"name":"小牧","age":"23"} } } ``` - **区别**:FastJSONJSON.toJSONString() 性能较高,但 Gson 更灵活,支持复杂注解(引用[2])[^3]。 **使用建议:** - **添加依赖**:在 Java 项目中使用时,需引入 FastJSON 或 Gson 库(如 Maven 依赖)。 - **自定义序列化**:通过实现 Serializer 接口或使用注解,实现类似 toJSON 的自定义逻辑。 - **错误处理**:确保对象可序列化,避免空指针异常(引用[4])。 --- ### 4. **总结和最佳实践** - **JavaScript 上下文**:toJSON 是对象的方法,用于自定义 JSON.stringify() 的输出。优先定义它来过滤或格式化数据。 - **Java 上下文**:JSON.toJSONString()(FastJSON)或 Gson.toJson() 是库方法,用于对象序列化。选择库时考虑性能和需求。 - **通用原则**: - 始终处理敏感数据:在 toJSON 或序列化方法中移除密码等字段。 - 测试边界情况:如循环引用或大数据集,确保稳定性(引用[4])[^5]。 - 参考官方文档:JavaScript 的 MDN 或 Java 库的 GitHub 页面。 通过合理使用这些方法,您可以高效控制 JSON 序列化,提升应用性能和数据安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值