视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
JSON.stringify()用法介绍
2020-11-27 20:14:14 责编:小采
文档


老司机们,你知道JSON.stringify还有第二个和第三个可选参数吗?它们是什么呢?是不是感到不可思议?下面这篇文章就来给大家介绍了一些你可能不知道的JSON.stringify的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。

前言

JSON已经逐渐替代XML被全世界的开发者广泛使用。本文深入讲解JavaScript中使用JSON.stringify的一些细节问题。首先简单回顾一下JSON和JavaScript:

  • 不是所有的合法的JSON都是有效的JavaScript;

  • JSON只是一个文本格式;

  • JSON中的数字是十进制。

  • 1. JSON.stringify

    JSON.stringify函数将一个JavaScript对象转换成文本化的JSON。不能被文本化的属性会被忽略。foo中属性b的值是函数定义,没有被转换而丢失。

    还有哪些属性也不能转换?

    1. 循环引用

    如果一个对象的属性值通过某种间接的方式指回该对象本身,那么就是一个循环引用。比如:

    属性c指向自己,如果层层解析,将会进入一个无限循环。我们尝试将其打印出来看看:

    c的属性指向foo对象,foo对象中的b属性又指向bar对象而无法处理,整个被忽略而返回空对象。

    如下定义(原文中的例子)是无法通过编译的:

    错误信息:

    在函数式语言Haskell中,因为有Lazy Evaluation技术,可以使用类似的定义方法。

    2. Symbol和undefined

    例外情况

    在数组中,不可被stringify的元素用null填充。

    这样可以保持数组本身的“形状”,也就是每一个元素原本的索引。

    为什么有些属性无法被stringify呢?

    因为JSON是一个通用的文本格式,和语言无关。设想如果将函数定义也stringify的话,如何判断是哪种语言,并且通过合适的方式将其呈现出来将会变得特别复杂。特别是和语言相关的一些特性,比如JavaScript中的Symbol。

    ECMASCript官方也特意强调了这一点:

    It does not attempt to impose ECMAScript's internal data representations on other programming languages. Instead, it shares a small subset of ECMAScript's textual representations with all other programming languages.

    2. 重写对象toJSON函数

    一个绕过对象某些属性无法stringify的方法就是实现对象的toJSON方法来自定义被stringify的对象。因为几乎每一个AJAX调用都会使用JSON.stringify,掌握该技巧将会对处理服务器交互有很大帮助。

    和toString允许你将对象中的元素以字符串(string)的形式返回类似,toJSON提供了一种可以将对象中不能stringify的属性转换的方法,使得接下来调用的JSON.stringify可以将其转换成JSON格式。

    Person实例ade的process函数没有被stringify。假想如果服务器只想要ade的全称,而不是分别获取姓和名,我们可以直接定义toJSON来达到目的:

    定义toJSON的优点是复用性和稳定性,你可以将ade配合任何库使用,传输的数据都将是你通过toJSON定义而返回的fullName。

    3. 可选参数

    JSON.stringify完整的定义如下:

    replacer和space都是可选参数,接下来我们来分别讲解。

    Replacer

    replacer是一个过滤函数或则一个数组包含要被stringify的属性名。如果没有定义,默认所有属性都被stringify。

    1. 数组

    只有在数组中的属性被stringify:

    嵌套属性也同样会被过滤:

    定义过滤数组有时候并不能满足需求,那么可以自定义过滤函数。

    2. 函数

    过滤函数以对象中的每一个属性和值作为输入,返回值有以下几种情况:

  • 返回undefined表示忽略该属性;

  • 返回字符串,布尔值或则数字将会被stringify;

  • 返回对象将会触发递归调用知道遇到基本类型的属性;

  • 返回无法stringify的值将会被忽略;

  • 通过改写上面的函数加入适当的输出,可以看到具体的执行步骤:

    space

    你是否意识到调用默认的JSON.stringify返回的值只要一行,而且完全没有空格?如果想要更加美观的打印出来,那么就需要使用space这个参数了。

    我告诉你一个非常简单的方法:通过tab(‘\t')来分割即可。

    一道三颗星的思考题:为什么打印结果的倒数第三行有两个a呢?

    结论

    本文介绍了一些使用toJSON的技巧:

  • 无法stringify的几种类型

  • 使用toJSON来自定义JSON.stringify的属性

  • 可选参数replacer的两种定义方法来过滤属性

  • 可选参数space用来格式化输出结果

  • 数组和对象中如果包含无法stringify的元素的时候的区别

  • 下载本文
    显示全文
    专题