json.stringify和tostring区别,json.stringify json.parse

  json.stringify和tostring区别,json.stringify json.parse

  真的会用强大的JSON.stringify方法吗?下面这篇文章带你详细了解JSON.stringify,并介绍它的用法。希望对你有帮助!

  JSON.stringify是日常开发中经常用到的。真的能灵活运用吗?

  在研究这篇文章之前,鲍晓希望每个人都带着几个问题来学习stringify。【相关推荐:javascript视频教程】

  Stringify函数有几个参数。每个参数有什么用?stringify的序列化标准是什么?函数序列化会做什么?null、undefined、NaN等特殊值怎么办?ES6和BigInt序列化后添加的符号类型会有什么特殊处理吗?为什么stringify不适合深度复制?你能想到stringify的这些妙用吗?文章的整个脉络和下面的思维导图是一致的,可以先做个印象。

  

三参数

  在日常编程中,我们经常使用JSON.stringify方法将一个对象转换成JSON字符串形式。

  const stu={

  姓名: zcxiaobao ,

  年龄:18岁

  }

  //{ 姓名: ZC小宝,年龄:18}

  console . log(JSON . stringify(stu));但是stringify真的那么简单吗?我们先来看看MDN中stringify的定义。

  MDN表示JSON.stringify()方法将JavaScript对象或值转换为JSON字符串。如果指定了replacer函数,则可以有选择地替换该值,或者如果指定的replacer是一个数组,则可以有选择地只包含该数组指定的属性。

  读完定义后,鲍晓很惊讶。stringfy是否有多个参数?当然,stringify有三个参数。

  让我们看看stringify语法和参数介绍:

  Json.stringify (value [,replacer [,space]]) value:要排序到Json字符串中的值。Replacer(可选)如果该参数为函数,则序列化过程中,序列化值的每个属性都将被该函数转换和处理;

  如果这个参数是数组,那么只有包含在这个数组中的属性名将被序列化为最终的JSON字符串。

  如果此参数为空或未提供,对象的所有属性都将被序列化。

  Space(可选):指定缩进的空白字符串,用于美化输出。如果参数是一个数字,它表示有多少个空格。上限是10。

  如果该值小于1,则意味着没有空格。

  如果参数是一个字符串(当字符串长度超过10个字母时,取前10个字母),该字符串将被用作空格。

  如果未提供该参数(或为空),则没有空格。

  

replacer

  让我们尝试使用replacer。

  作为函数的替换器

  作为一个函数,replacer有两个参数,key和值,这两个参数都将被序列化。

  一开始,replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。重要的是要理解replacer函数在出现时并不把对象解析成键值对,而是先传入待序列化对象。然后每个对象或数组上的属性将依次传入。如果函数返回值为undefined或者函数时,该属性值会被过滤掉,其余按退货规则。

  //replacer接受两个参数键值。

  //键值是对象的每个键值对。

  //所以我们可以简单地根据键或值的类型进行过滤

  函数替换器(键,值){

  if (typeof value===string) {

  返回未定义的;

  }

  返回值;

  }

  //函数可以自己测试。

  函数replacerFunc(key,value) {

  if (typeof value===string) {

  return()={ };

  }

  返回值;

  }

  const foo={foundation: Mozilla ,model: box ,周:45,transport: car ,月:7 };

  const JSON string=JSON . stringify(foo,replacer);JSON序列化结果是{week:45, month:7}

  但是,如果数组是序列化的,如果replacer函数返回undefined或function,则当前值不会被忽略,而是被null替换。

  const list=[1, 22 ,3]

  constjsonstring=JSON . stringify(list,replacer)JSON序列化的结果是[1,null,3]

  以数组形式替换

  由于数组很容易理解,所以过滤数组中出现的键值。

  const foo={foundation: Mozilla ,model: box ,周:45,transport: car ,月:7 };

  const JSON字符串=JSON。stringify(foo,[week , month ]);数据序列化结果为{ 周:45,月:7},只保留周和月属性值。

  

九特性

  

特性一: undefined、函数、Symbol值

   出现在非数组对象属性值中:未定义,任意函数、符号值在序列化过程中将会被忽略

  出现在数组中:未定义,任意函数、符号值会被转化为null

  单独转换时:会返回undefined

  //1.对象属性值中存在这三种值会被忽略

  const obj={

  姓名: zc ,

  年龄:18,

  //函数会被忽略

  说你好(){

  console.log(hello world )

  },

  //未定义会被忽略

  妻子:未定义,

  //符号值会被忽略

  id:符号(111),

  //[符号( zc)]: zc ,

  }

  //输出结果:{ 姓名: zc ,年龄:18}

  控制台。log(JSON。stringify(obj));

  //2.数组中这三种值会被转化为空

  常量列表=[

  zc ,

  18,

  //函数转化为空

  函数说你好(){

  console.log(hello world )

  },

  //未定义转换为空

  未定义,

  //符号转换为空

  符号(111)

  ]

  //[zc ,18,null,null,null]

  控制台。log(JSON。stringify(列表))

  //3.这三种值单独转化将会返回不明确的

  控制台。log(JSON。stringify(未定义))//未定义

  控制台。log(JSON。stringify(符号(111))//未定义

  console.log(JSON.stringify(函数说你好(){

  console.log(hello world )

  })) //未定义

特性二: toJSON() 方法

  转换值如果有托伊森方法,托吉森()方法返回什么值,序列化结果就返回什么值,其余值会被忽略。

  const obj={

  姓名: zc ,

  toJSON(){

  return return toJSON

  }

  }

  //返回到杰森

  控制台。log(JSON。stringify(obj));

特性三: 布尔值、数字、字符串的包装对象

  布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值

  JSON。stringify([新数字(1),新字符串( zcxiaobao ),新布尔(真)]);

  //[1, zcxiaobao ,true]

特性四: NaN Infinity null

  特性四主要针对Java脚本语言里面的特殊值,例如数字类型里的圆盘烤饼和无穷及零。此三种数值序列化过程中都会被当做 null

  //[空,空,空,空,空]

  JSON.stringify([null,NaN,-NaN,Infinity,-Infinity])

  //特性三讲过布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值

  //隐式类型转换就会调用包装类,因此会先调用数字=南

  //之后再转化为空

  //1/0=无穷大=空

  JSON。stringify([数字( 123a , 123a ,1/0])

特性五: Date对象

  日期对象上部署了托吉森方法(同Date.toISOString())将其转换为字符串,因此JSON.stringify() 将会序列化 Date 的值为时间格式字符串

  //2022-03-06T08:24:56.138Z

  JSON.stringify(新日期())

特性六: Symbol

  特性一提到,符号类型当作值来使用时,对象、数组、单独使用分别会被忽略、转换为零,转化为未定义。

  同样的,所有以 Symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们

  const obj={

  姓名: zcxiaobao ,

  年龄:18,

  [符号( lyl)]:唯一

  }

  函数替换器(键,值){

  if (typeof key===symbol) {

  返回值;

  }

  }

  //未定义

  JSON.stringify(obj,replacer);通过上面案例,我们可以看出,虽然我们通过替代者强行指定了返回标志类型值,但最终还是会被忽略掉。

  

特性七: BigInt

   JSON.stringify规定:尝试去转换 BigInt 类型的值会抛出 TypeError

  const bigNumber=BigInt(1)

  //未捕获的类型错误:不知道如何序列化大整数

  控制台。log(JSON。stringify(大数字))

特性八: 循环引用

  特性八指出:对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误

  日常开发中深拷贝最简单暴力的方式就是使用JSON.parse(JSON.stringify(obj)),但此方法下的深拷贝存在巨坑,关键问题就在于字符串化无法处理循环引用问题。

  const obj={

  姓名: zcxiaobao ,

  年龄:18,

  }

  const loopObj={

  目标文件

  }

  //形成循环引用

  obj。loop obj=loop obj

  JSON.stringify(obj)

  /*未捕获的类型错误:将循环结构转换为数据

  -从具有构造函数"对象"的对象开始

  属性"循环对象"具有构造函数"对象"的对象

  -属性" obj "封闭循环

  在JSON.stringify(匿名)

  在无名氏:10:6

  */

特性九: 可枚举属性

   对于对象(包括地图/套件/WeakMap/WeakSet)的序列化,除了上文讲到的一些情况,纤细的也明确规定,仅会序列化可枚举的属性

  //不可枚举的属性默认会被忽略

  //{ 年龄:18}

  JSON.stringify(

  对象.创建(

  空,

  {

  名称:{ value: zcxiaobao ,可枚举:false },

  年龄:{值:18,可枚举:真}

  }

  )

  );

六妙用

  

localStorage

   localStorage对象用于长期存储整个网站的数据,存储的数据没有过期时间,直到被手动删除。我们通常将它存储为一个对象。

  调用localStorage对象方法。

  const obj={

  姓名: zcxiaobao ,

  年龄:18岁

  }

  //只需调用localStorage.setItem()

  localStorage.setItem(zc ,obj);

  //最终返回结果是[object Object]

  //可以看出,单纯调用localStorage是失败的。

  console . log(localstorage . getitem( ZC ))使用JSON.stringify方法的local storage

  localStorage.setItem(zc ,JSON . stringify(obj));

  //最后返回的结果是{name: zcxiaobao ,年龄:18}

  console . log(JSON . parse(localStorage . getitem( ZC ))

属性过滤

  假设这样一个场景,后端返回一个很长的对象,对象中有很多属性,但是我们只需要其中的几个,这些属性是要存储在local storage中的。

  方案1:解构赋值字符串

  //我们只需要一个,e,f属性

  const obj={

  a:1,b:2,c:3,d:4,e:5,f:6,g:7

  }

  //解构赋值

  const {a,e,f }=obj

  //存储到本地存储

  localStorage.setItem(zc ,JSON.stringify({a,e,f}))

  //{a:1, e:5, f:6}

  console . log(local storage . getitem( ZC ))使用stringify的replacer参数。

  //借助replacer作为数组过滤

  localStorage.setItem(zc ,JSON.stringify(obj,[a , e , f]))

  //{a:1, e:5, f:6}

  console . log(local storage . getitem( ZC ))当replacer是一个数组时,它可以简单地过滤掉我们需要的属性,这是一个很好的技巧。

  

三思而后行之深拷贝

  使用JSON.parse(JSON.stringify)是实现对象深度复制的最简单也是最暴力的方法之一。但如题,这种方法的深度复制要慎重考虑。

  循环引用问题,stringify将报告错误

  函数,未定义,符号被忽略。

  NaN、Infinity和-Infinity被序列化为null。

  .

  所以在使用JSON.parse(JSON.stringify)做深度复制的时候,一定要慎重考虑。没有以上隐患,JSON.parse(JSON.stringify)是一个可行的深度复制方案。

  

对象的 map 函数

  用数组编程时,我们经常使用map函数。有了replacer参数,我们就可以用这个参数来实现对象的贴图功能。

  const ObjectMap=(obj,fn)={

  if (typeof fn!==函数){

  throw new TypeError(`${fn}不是函数!`);

  }

  //首先调用JSON.stringify(obj,replacer)实现map函数。

  //然后调用JSON.parse将其再次转换为对象

  返回JSON.parse(JSON.stringify(obj,fn));

  };

  //例如,将obj对象的属性值乘以下面的2

  const obj={

  答:1,

  乙:2,

  丙:3

  }

  console.log(ObjectMap(obj,(key,val)={

  if (typeof value===number) {

  返回值* 2;

  }

  返回值;

  }))很多同学可能会很奇怪。为什么要在里面多加一个判词?就不能返回值* 2吗?

  如上所述,replacer函数首先传入要序列化的对象对象 * 2 = NaN = toJSON(NaN) = undefined = 被忽略,因此没有后续的键值对解析。

  

删除对象属性

  借助replacer函数,我们还可以删除对象的一些属性。

  const obj={

  姓名: zcxiaobao ,

  年龄:18岁

  }

  //{ 年龄:18}

  JSON.stringify(obj,(key,val)={

  //当返回值未定义时,该属性将被忽略

  if (key===name) {

  返回未定义的;

  }

  返回val

  })

对象判断

   JSON.stringify可以将对象序列化为字符串,所以我们可以借助字符串实现简单的对象相等判断。

  //确定数组是否包含对象

  常量名称=[

  {姓名: zcxiaobao},

  {name:txtx},

  {姓名:我的 },

  ];

  const ZC xiaobao={ name: ZC xiaobao };

  //真

  JSON.stringify(名称)。包括(JSON.stringify(zcxiaobao))

  //确定对象是否相等

  const d1={type: div}

  const d2={type: div}

  //真

  JSON . stringify(D1)===JSON . stringify(D2);

数组对象去重

  借助以上思路,我们还可以实现数组对象的简单去重。

  但是因为JSON.stringify序列化{x:1,y:1}和{y:1,x:1}的结果不同,所以我们需要在开始之前处理数组中的对象。

  方法1:按字典顺序排列数组中每个对象的键。

  arr.forEach(item={

  const new item={ };

  Object.keys(item) //获取对象键值。sort() //键值排序。map(key={//生成新对象

  new item[key]=item[key];

  })

  //使用newItem执行重复数据删除操作

  })但是第一种方法有些繁琐。JSON.stringify提供了replacer数组格式参数,可以过滤数组。

  方法2:借助replacer数组格式

  唯一函数(arr) {

  const key Set=new Set();

  const uniqueObj={}

  //提取所有密钥

  arr.forEach(item={

  Object.keys(项目)。forEach(key=keySet.add(key))

  })

  const replacer=[.密钥集];

  arr.forEach(item={

  //根据指定的键值替换器过滤所有对象

  unique[JSON.stringify(item,replacer)]=item;

  })

  返回Object.keys(唯一)。map(u=JSON.parse(u))

  }

  //测试一下

  唯一([{},{},

  {x:1},

  {x:1},

  {a:1},

  {x:1,a:1},

  {x:1,a:1},

  {x:1,a:1,b:1}

  ])

  //返回结果

  [{},{x: 1},{a: 1},{x: 1},{x: 1, a: 1, b :1 }][相关推荐:web前端]以上就是带你穿越JSON。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: