前言

工作中经常使用 JSON.stringify 方法存储 localStorage,深拷贝对象,用的最多的就是第一个参数,甚至不知道它还有第二个和第三个参数,所以详细的整理了一下 JSON.stringify 用法和特性,使我们能够真正的能灵活运用这个方法。

语法

JSON.stringify(value[, replacer [, space]])

参数

replacer 参数

replacer 参数可以是一个函数或者一个数组。作为函数,它有两个参数,键(key)和值(value),它们都会被序列化。

值得注意的是,在开始时, replacer 函数会被传入一个空字符串作为 key 值,value代表着要被 stringify 的这个对象。随后每个对象或数组上的属性会被依次传入。

总的来说 replacer 参数就是用来手动忽略一些不想被序列化的属性,有点类似过滤器的作用

var foo = {
  id: 1,
  name: "sf",
  age: 18,
};
//作为函数,函数没有返回值或者返回值为 undefined 时,忽略这个属性值
JSON.stringify(foo, (key, value) => {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
});
//{"id":1,"age":18}

//作为数组,数组的值代表将被序列化成 JSON 字符串的属性名
JSON.stringify(foo, ['id',"name"]);
//{"id":1,"name":"sf"}

space 参数

space 参数用来控制结果字符串里面的间距。如果是一个数字, 则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多10个空格);如果是一个字符串,则每一级别会比上一级别多缩进该字符串(或该字符串的前10个字符)。实际使用基本都是用来美化输出。

let a = JSON.stringify({ a: 1, b: 2 }, null, 2);
let b = JSON.stringify({ a: 1, b: 2 }, null, "  ");
console.log(a == b); //true

JSON.stringify({ a: 1, b: 2 }, null, "--");
// {
// --"a": 1,
// --"b": 2
// }

特性描述

1. undefined、Symbol值、函数

  • 出现在对象属性值中: undefined、Symbol值、函数,在序列化过程中将会被忽略
  • 出现在数组中: undefined、Symbol值、函数 会被转化为 null
  • 单独转换时: 会返回 undefined
const obj = {
  a: "a",
  b: undefined,
  c: Symbol(),
  d: function () {},
};
JSON.stringify(obj)
// {"a":"a"}
const arry = [undefined, Symbol("c"), function () {}];
JSON.stringify(arry); 
//[null,null,null]
JSON.stringify(undefined); 
// undefined
JSON.stringify(Symbol(111));
// undefined
JSON.stringify(function () {});
// undefined

2. 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中

正如在第一特性所说,JSON.stringify() 序列化时会忽略一些特殊的值,所以不能保证序列化后的字符串还是以特定的顺序出现(数组除外)。

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

JSON.stringify([new Boolean(true), new Number(1), new String("a")]);
// [true,1,"a"]

4. 转换值如果有 toJSON() 方法,该方法定义什么值将被序列化

const obj = {
  a: "aaa",
  toJSON() {
    return "hello world";
  },
};
JSON.stringify(obj);
// "hello world"

5. 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。

const obj = {
  name: "loopObj",
};
const loopObj = {
  obj,
};
// 对象之间形成循环引用,形成闭环
obj.loopObj = loopObj;
JSON.stringify(obj);
//TypeError: Converting circular structure to JSON

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

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

const obj = {
  a: "aaa",
  [Symbol("foo")]: "foo",
};
JSON.stringify(obj);
// {"a":"aaa"}
JSON.stringify(obj, function (k, v) {
  if (typeof k === "symbol") {
    return "a symbol";
  }
});
// undefined

7. 日期调用了 toJSON() 将其转换为了 string 字符串(同Date.toISOString()),因此会被当做字符串处理。

JSON.stringify({
  date: new Date("2022-02-02"),
})
// {"date":"2022-02-02T00:00:00.000Z"}

8. NaN 和 Infinity 格式的数值及 null 都会被当做 null。

JSON.stringify([NaN, Infinity, 1 / 0, Number("a")]);
// [null,null,null,null]

9. 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。

// 不可枚举的属性默认会被忽略:
JSON.stringify(
  Object.create(null, {
    x: { value: "x", enumerable: false },
    y: { value: "y", enumerable: true },
  })
);
// "{"y":"y"}"

应用

localStorage

localStorage 中的键值对总是以字符串的形式存储,所以当我们需要把一个对象存在 localStorage 中时,只能用 JSON.stringify 将其转化成字符串存储,使用的时候用 JSON.parse 方法去取

const userInfo = { user: "admin" };
localStorage.setItem("userInfo", JSON.stringify(userInfo));
JSON.parse(localStorage.getItem("userInfo"));
// {user: 'admin'}

对象深拷贝

使用 JSON.parse(JSON.stringify) 是实现对象的深拷贝最简单粗暴的方法。但是由于 JSON.stringify 的一些特性,会产生问题,例如:

  • undefined、Symbol、 函数, 对象中会被忽略,数组中会被序列化成 null。
  • NaN、Infinity 和 -Infinity 会被序列化成 null。
  • 循环引用问题,stringify 会报错。

当确定不存在以上情况时,才考虑使用 JSON.parse(JSON.stringify) 进行深拷贝。

属性过滤

当接口返回一大堆数据,我们只想存某几个属性的时候,通过 replacer 函数过滤属性是一个不错的小技巧。

var foo = {
  id: 1,
  name: "sf",
  age: 18,
};
localStorage.setItem("user", JSON.stringify(foo, ["id", "name"]));
localStorage.getItem("user");
//{"id":1,"name":"sf"}

总结

到此这篇关于JSON.stringify实例详解以及灵活运用的文章就介绍到这了,更多相关JSON.stringify运用内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

JSON.stringify实例详解以及灵活运用的更多相关文章

  1. AngularJS下$http服务Post方法传递json参数的实例

    下面小编就为大家分享一篇AngularJS下$http服务Post方法传递json参数的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  2. php检查函数必传参数是否存在的实例详解

    这篇文章主要介绍了php检查函数必传参数是否存在的实例详解的相关资料,需要的朋友可以参考下

  3. vue-router如何实时动态替换路由参数(地址栏参数)

    这篇文章主要介绍了vue-router如何实时动态替换路由参数(地址栏参数),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  4. redirect_uri参数错误的解决方法(必看)

    下面小编就为大家带来一篇redirect_uri参数错误的解决方法(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. 深入理解JS函数的参数(arguments)的使用

    下面小编就为大家带来一篇深入理解JS函数的参数(arguments)的使用。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. 通过实例了解js函数中参数的传递

    这篇文章主要介绍了通过实例了解js函数中参数的传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下

  7. ajax获取php页面的返回参数,控件赋值的方法

    下面小编就为大家带来一篇ajax获取php页面的返回参数,控件赋值的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. Python实现解析参数的三种方法详解

    这篇文章主要介绍了python解析参数的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  9. JSON.stringify的多种用法总结

    这篇文章主要给大家介绍了关于JSON.stringify使用的相关资料, JSON.stringify()方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,需要的朋友可以参考下

  10. 利用 kotlin 的方式自定义回调事件(kotlin函数参数)

    这篇文章主要介绍了利用 kotlin 的方式自定义回调事件(kotlin函数参数),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部