为什么 String 跟 JSON 不是同个东西?

举报
yd_244540595 发表于 2024/10/10 16:54:02 2024/10/10
【摘要】 作者:大码猴  来源:juejin.cn/post/7379884568579555355很多人会误解JSON仅仅是序列化后的String,但这样的表述并不完全准确。JSON本质上是以字符串(String)形式表示的数据交换格式,但它不仅仅是一个字符串,而是具有特定语法和结构的字符串。很经常遇到的一个场景: 后端:我给你返回了一段JSON,你转化下再遍历吧。 等前端拿到的时候傻眼了。前端:喂...

作者:大码猴  
来源:juejin.cn/post/7379884568579555355

很多人会误解JSON仅仅是序列化后的String,但这样的表述并不完全准确。JSON本质上是以字符串(String)形式表示的数据交换格式,但它不仅仅是一个字符串,而是具有特定语法和结构的字符串。

很经常遇到的一个场景:
后端:我给你返回了一段JSON,你转化下再遍历吧。
等前端拿到的时候傻眼了。

image.png

前端:喂,真的是JSON?
后端: 千真万确!

那么JSON跟String怎么区分?

(顺便吆喝一句,技术大厂,前后端测试捞人)

  1. 本质

    • String:是一个基本数据类型,用于表示一系列字符(例如文本、数字、符号等)。在前端中,字符串是用单引号(')、双引号(")或反引号(```)括起来的字符序列。
    • JSON:是一种轻量级的数据交换格式。它易于人阅读和编写,同时也易于浏览器解析和生成。在前端中,JSON对象通常被解析为对象、数组、字符串、数字、布尔值或null
  2. 用途

    • String:在前端开发中,字符串用于存储和表示文本数据。它们可以被用于各种目的,包括显示给用户、与其他服务器通信、处理文本数据等。
    • JSON:JSON主要用于存储和交换数据。它经常被用于在服务器和客户端之间传输数据。JSON数据可以很容易地被JavaScript解析,使其成为开发中非常流行的数据格式。
  3. 语法

    • String:在JavaScript中,字符串的语法相对简单,只需要用引号(“”)将字符序列括起来即可。
    • JSON:JSON的语法更加严格,因为它需要遵循特定的格式。例如,所有的字符串都必须用双引号括起来,对象的键也必须是双引号括起来的字符串。此外,JSON不支持JavaScript中的一些功能,如函数和undefined
  4. 转换

    • 在开发中,我们可以很容易地将JSON字符串解析为JavaScript对象(使用JSON.parse()方法),或者将JavaScript对象转换为JSON字符串(使用JSON.stringify()方法)。

下面是一个简单的例子来说明这种区别:

// 这是一个字符串  
let str = "Hello, World!";  
  
// 这是一个JSON字符串(注意双引号和对象的格式)  
let jsonStr = '{"name": "张三", "age": 30, "city": "上海"}';  
  
// 将JSON字符串解析为JavaScript对象  
let obj = JSON.parse(jsonStr);  
console.log(obj.name); // 输出 "张三"  
  
// 将JavaScript对象转换为JSON字符串  
let jsonStr2 = JSON.stringify(obj);  
console.log(jsonStr2); // 输出 '{"name":"张三","age":30,"city":"上海"}'

在这个例子中,str是一个字符串,而jsonStr是一个JSON字符串。通过JSON.parse()方法,我们可以将jsonStr解析为一个JavaScript对象obj。同样地,通过JSON.stringify()方法,我们可以将obj转换回一个JSON字符串jsonStr2

再来个标准的JSON对象跟String伪对象的区别:


javascript
代码解读
复制代码
      const stringObj = "{'text': 'string obj'}";
      const jsonObj = '{"text": "JSON Obj"}';

      console.log(
       "stringObj: " + typeof stringObj
      )

      console.log(
        "jsonObj: " + typeof jsonObj
      )

      console.log(
        "jsonObj: ", JSON.parse(jsonObj)
      )

      console.log(
        "stringObj: ", JSON.parse(stringObj)  // 报错,不是一个正规格式的JSON
      )

image.png

这两个"JSON"看起来很相似,stringObj 是一个字符串字面量,其内容是一个看起来像 JSON 但实际上是用单引号包裹键和字符串值的非标准 JSON 格式。在 JavaScript 中,JSON 对象的键和字符串值通常使用双引号。

那么当后端返回一个string的伪JSON时,我们该怎么去解决呢


typescript
代码解读
复制代码
const strJson = <T>(
  str: string
): T => {

  if(typeOf(str) !== 'string') {
    return str as any
  }

  try {
    return JSON.parse(str)
  } catch {
    return (new Function(`return ${str}`)())
  }
}

接受一个参数,如果本身不是string则直接返回,如果 JSON.parse(str) 抛出异常(即 str 不是一个有效的 JSON 字符串),函数会捕获这个异常,并尝试通过创建一个新的函数并执行它来处理 str。有同学就会说这个直接执行str不安全,可以多加几道防护去过滤。

注意:可以使用eval代替new Function

我们拿上面例子2为例,看能不能处理这个伪JSON


arduino
代码解读
复制代码
  console.log(strJson(stringObj))
  console.log(strJson(jsonObj))

image.png

这当然是可以的啦,再也不怕拿到伪JSON

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。