90%前端只会皮毛!JSON.parse/stringify高阶用法、数据规则、避坑终极指南

一、前言

在 JavaScript 开发中,JSON.parse()JSON.stringify() 是使用率极高的一对核心方法,主要用于 JSON 字符串与 JS 对象的相互转换

绝大多数开发者只会基础用法,却不了解深层参数、转换规则、特殊数据丢失、循环引用报错、序列化异常等高频坑点。

本文从零拆解两个方法的基础语法、完整参数、实战场景、核心区别、全网高频避坑点,一篇彻底吃透,适配日常开发、面试手撕、数据处理全场景。

二、核心本质一句话区分

  • JSON.stringify()序列化,JS 对象/数组 → JSON 字符串(输出字符串)
  • JSON.parse()反序列化,JSON 字符串 → JS 对象/数组(还原对象)

简单记忆:stringify 转字符串,parse 解字符串

三、JSON.stringify() 超全详解(序列化)

1、基础作用

将 JavaScript 引用类型数据(对象、数组)转换为 标准 JSON 格式字符串,常用于数据存储、本地缓存、接口传参、深拷贝等场景。

2、基础语法

javascript 复制代码
JSON.stringify(value, replacer, space)

参数说明:

  • value(必传) :需要序列化的 JS 对象、数组、基础数据
  • replacer(可选) :过滤/转换函数或数组,用于筛选、修改序列化字段
  • space(可选) :缩进空格数,用于格式化输出 JSON 字符串

3、基础用法示例

javascript 复制代码
const obj = { name: '前端开发', age: 20, hobby: 'coding' }

// 对象转 JSON 字符串
const jsonStr = JSON.stringify(obj)
console.log(jsonStr)
// 输出:{"name":"前端开发","age":20,"hobby":"coding"}
console.log(typeof jsonStr) // string

4、高阶参数实战用法

4.1 第二个参数:数组过滤指定字段

只序列化数组中配置的字段,其余字段直接过滤丢弃。

javascript 复制代码
const obj = { name: '前端开发', age: 20, hobby: 'coding' }
// 仅保留 name、age 字段
const jsonStr = JSON.stringify(obj, ['name', 'age'])
console.log(jsonStr)
// 输出:{"name":"前端开发","age":20}

4.2 第二个参数:函数自定义处理字段

可对序列化的 键值对 做自定义拦截、修改、重置逻辑。

javascript 复制代码
const obj = { name: '前端开发', age: 20, hobby: 'coding' }

const jsonStr = JSON.stringify(obj, (key, value) => {
  // 对age字段单独处理
  if (key === 'age') return 99
  return value
})
console.log(jsonStr)
// 输出:{"name":"前端开发","age":99,"hobby":"coding"}

4.3 第三个参数:格式化缩进输出

默认压缩输出,设置数值(1-10)可自动缩进格式化,方便日志查看。

javascript 复制代码
const obj = { name: '前端开发', age: 20 }
const jsonStr = JSON.stringify(obj, null, 2)
console.log(jsonStr)
// 格式化缩进输出

四、JSON.parse() 超全详解(反序列化)

1、基础作用

将标准 JSON 格式字符串,还原为 原生 JS 对象/数组,是序列化的反向操作,常用于后端数据解析、本地缓存数据读取。

2、基础语法

arduino 复制代码
JSON.parse(text, reviver)

参数说明:

  • text(必传) :标准合法的 JSON 字符串
  • reviver(可选) :回调函数,用于解析时二次处理键值对数据

3、基础用法示例

javascript 复制代码
const jsonStr = '{"name":"前端开发","age":20}'
// 字符串转 JS 对象
const obj = JSON.parse(jsonStr)
console.log(obj) // { name: '前端开发', age: 20 }
console.log(typeof obj) // object

4、高阶参数:reviver 数据二次处理

解析过程中可对指定字段做类型转换、数值修改、数据过滤

javascript 复制代码
const jsonStr = '{"name":"前端开发","age":20}'
const obj = JSON.parse(jsonStr, (key, value) => {
  // 将age转为字符串
  if (key === 'age') return String(value)
  return value
})
console.log(obj.age, typeof obj.age) // '20' string

五、开发高频实战场景(必用)

1、localStorage 本地缓存数据

本地存储只能存字符串,对象/数组必须先序列化,读取后反序列化还原。

javascript 复制代码
const user = { name: 'test', id: 1001 }
// 存储:对象转字符串
localStorage.setItem('user', JSON.stringify(user))
// 读取:字符串转对象
const userInfo = JSON.parse(localStorage.getItem('user'))

2、简单深拷贝(经典面试题)

通过序列化+反序列化,快速实现对象/数组深拷贝,零依赖、写法极简。

javascript 复制代码
const originObj = { name: '前端', info: { age: 20 } }
// 深拷贝核心写法
const newObj = JSON.parse(JSON.stringify(originObj))

3、接口参数格式化、数据过滤

通过 stringify 第二个参数过滤无效字段、空字段,精简接口传参。

4、Vue3 专属高频实战案例(项目必用)

在 Vue3 + Vite 项目中,JSON 的序列化与反序列化是本地持久化、组件复杂传参、响应式数据处理的核心操作,下面分享 4 个可直接复制上线的高频实战案例。

案例1:Vue3 本地持久化响应式用户数据

Vue3 项目中常用 Pinia / localStorage 存储用户信息,对象类型数据必须通过 JSON 方法转换,否则会出现数据存储失效、读取异常问题。

xml 复制代码
<script setup>
import { ref } from 'vue'

// 定义响应式用户数据
const userInfo = ref({
  name: '前端开发者',
  age: 22,
  token: 'xxxxxxx'
})

// 数据持久化:序列化存储
const saveUserInfo = () => {
  localStorage.setItem('userInfo', JSON.stringify(userInfo.value))
}

// 页面初始化读取:反序列化还原
const getUserInfo = () => {
  const str = localStorage.getItem('userInfo')
  if (str) {
    userInfo.value = JSON.parse(str)
  }
}

// 页面加载读取数据
getUserInfo()
</script>

案例2:Vue3 父子组件复杂对象传参

Vue3 组件传参基础类型可直接传递,复杂对象、数组、多层嵌套数据可通过 JSON 序列化传参,规避响应式失效、数据双向污染问题。

父组件 Father.vue

xml 复制代码
<template>
  <!-- 序列化后传递字符串,避免子组件篡改父组件原始数据 -->
  <Child :list="JSON.stringify(tableList)" />
</template>

<script setup>
import Child from './Child.vue'
import { ref } from 'vue'

// 复杂嵌套数组数据
const tableList = ref([
  { id: 1, title: 'Vue3实战', status: 1 },
  { id: 2, title: 'JSON解析', status: 0 }
])
</script>

子组件 Child.vue

xml 复制代码
<script setup>
import { defineProps } from 'vue'

// 接收字符串,解析还原为数组
const props = defineProps(['list'])
const list = JSON.parse(props.list)

console.log(list) // 正常获取数组数据
</script>

案例3:Vue3 路由复杂参数传参(解决params丢失)

Vue3 路由 params 传参刷新页面丢失 ,可通过 JSON.stringify 序列化后放入 query 传递,实现刷新不丢失,完美解决路由传参痛点。

xml 复制代码
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()

// 复杂对象参数
const detailData = { id: 1001, name: '详情数据', list: [1,2,3] }

// 跳转页面,序列化复杂对象存入query
const goDetail = () => {
  router.push({
    path: '/detail',
    query: {
      info: JSON.stringify(detailData)
    }
  })
}
</script>

目标页面接收解析:

xml 复制代码
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()

// 解析还原复杂对象,刷新页面不丢失数据
const info = JSON.parse(route.query.info)
console.log(info)
</script>

案例4:Vue3 表单数据格式化提交(过滤空值)

借助 JSON.stringify 第二个参数,自动过滤表单空字段、无效字段,精简请求参数,适配后端接口参数校验规则。

xml 复制代码
<script setup>
import { ref } from 'vue'
import axios from 'axios'

// 表单数据
const form = ref({
  name: 'Vue3',
  age: '',
  desc: '前端实战',
  type: null
})

// 过滤空值、null值字段
const submitForm = async () => {
  const params = JSON.parse(JSON.stringify(form.value, (key, val) => {
    // 过滤空字符串、null、undefined
    if (val === '' || val === null || val === undefined) return undefined
    return val
  }))
  // 接口提交精简后的数据
  await axios.post('/api/submit', params)
}
</script>

Vue3 使用核心注意点

  • 响应式数据转换 :处理 ref/reactive 响应式数据时,必须取 .value 原值再序列化,否则会打包响应式代理标识,数据异常
  • 防止数据污染:组件传参序列化传递字符串,可切断引用关系,杜绝子组件篡改父组件原始数据
  • 路由参数兼容:复杂对象路由传参优先序列化存入 query,彻底解决 params 刷新丢失问题
  • 表单优化:利用高阶参数自动过滤无效参数,减少后端参数报错,精简请求体积

六、核心转换规则(避坑基础)

很多数据异常、丢失问题,都源于不了解 JSON 序列化规则:

  • undefined、函数、Symbol:序列化时直接丢失、忽略
  • NaN、Infinity、-Infinity :序列化后变为 null
  • Date 对象:序列化后转为 ISO 时间字符串,不再是 Date 对象
  • 正则、Error 对象 :序列化后变为空对象 {}
  • 循环引用对象 :直接报错 TypeError
  • 键名单引号、换行、特殊格式:非标准 JSON 字符串,parse 直接报错

七、全网高频坑点与解决方案(重点)

坑点1:深拷贝丢失特殊数据

通过 JSON 深拷贝时,undefined、函数、正则等数据会丢失,复杂对象不建议使用该方式深拷贝。

坑点2:parse 解析报错

报错原因:JSON 字符串不标准(键名单引号、尾部逗号、换行、特殊字符)

解决方案:使用 try-catch 包裹,防止页面崩溃

javascript 复制代码
function safeParse(str) {
  try {
    return JSON.parse(str)
  } catch (err) {
    return null
  }
}

坑点3:循环引用序列化报错

ini 复制代码
const obj = {}
obj.self = obj
// 报错:Converting circular structure to JSON
JSON.stringify(obj)

解决:自定义过滤函数,剔除循环引用字段。

坑点4:null、undefined 转换差异

undefined 在对象中会被忽略,单独序列化会返回 undefined;null 可正常序列化保留。

八、二者核心区别总结(面试必背)

方法 作用 转换方向 核心用途
JSON.stringify() 序列化 JS数据 → JSON字符串 数据存储、缓存、传参、格式化
JSON.parse() 反序列化 JSON字符串 → JS数据 解析后端数据、读取缓存数据

九、最终总结

1、JSON.stringify:对象转字符串,支持字段过滤、格式化输出,常用于数据存储传输;

2、JSON.parse:字符串还原对象,支持解析后数据二次处理,常用于数据解析;

3、JSON 转换存在严格数据规则,特殊数据会丢失、异常,需规避循环引用、非标准字符串等坑点;

4、简单深拷贝、本地缓存、接口传参是日常开发最高频的使用场景。

相关推荐
需要坚持的人1 小时前
让 SVG 不再“丢字变形”:一次思维导图导出文字转 Path 的实战优化
前端·vue.js·svg
sp421 小时前
NativeScript 5.1:直接集成 Objective-C 代码
前端·javascript
UXbot1 小时前
AI一次生成iOS和Android双端原型功能详解
android·前端·ios·kotlin·交互·swift
我是卡卡啊1 小时前
View 绘制深度分析:HWUI · RenderThread · SurfaceFlinger
前端
产品经理爱开发1 小时前
国内免费快速HTML托管平台推荐:优先艾可秀,零门槛秒上线
前端·html
蜡台1 小时前
idea 配置 vue 运行命令时, scripts 一栏始终为空
前端·vue.js·intellij-idea
杨前端布洛芬1 小时前
仿某钉打卡 UniApp 版
前端
超绝大帅哥1 小时前
RAG检索策略及划分策略
前端
小盼江1 小时前
Uniapp小程序鲜花商城推荐系统 买家卖家双端(web+uniapp)
前端·小程序·uni-app