分类: 技术

stringify 实现及 JSON 数据类型思考

背景

记之前遇见的一道面试题,让现场写出 JavaScript 中stringify函数的实现。首先写一下自己最开始的思路,然后针对里面的一些问题进行逐步修改,并且引出对 JSON 这种轻量级数据传输格式所拥有数据类型的学习与思考。

一、最初实现

首先给定题目

将一个 JSON 格式对象转换为字符串,转换后的结果可以通过JSON.parse()方法将该字符串重新转换为一个 JSON 对象。

先简化问题,将数据类型简单划分(并不正确,下文会给描述)为:对象(Object)、数组(Array)和字符串(String)这三种类型。对于 String,只需要简单的对它进行toString()调用,并包裹在"中处理,对于前两者则需要采取不同操作。考虑到他们的子元素也是 JSON 对象,定义具有递归性,所以代码也采用递归来实现。最初代码如下:

代码的思路就是传入一个对象,然后判断它的类型:1. 如果非数组和对象类型,就直接返回它的字符串形式;2. 如果是对象类型,则遍历每个键值对,判断每个键对应值的类型,如果是非字符串,则递归对它调用函数本身,否则直接在结果字符串中拼接他的字符串形式;3. 数组类型类似对象类型处理。这也是自己在面试中完成的版本。

二、类型问题

面试官又询问了是否可以保存 function 这种类型,其实这就牵扯到 JSON 这种数据格式所拥有的数据类型问题,JSON 是没有 function 这种数据类型的。其实可以想一下,JSON 的的目的是为了方便数据传输,而且其它语言也都有很多系统提供的库来处理 JSON,但其它语言并没有必要接收 function 这种类型,因为并没有办法直接执行,存储它也没有太大意义。

于是查找 JSON 的官方定义或者这篇文章,可以看到 JSON 的数据格式包括:

  1. Number
  2. String
  3. Boolean
  4. value
  5. Array
  6. Object
  7. Whitespace
  8. null

所以上面的代码是没有针对 Number / Boolean / null 这3种数据类型做处理的。针对这三种类型(其中 Boolean 需要判断truefalse两种情况),只要对他们进行toString()处理,而不要在外面包裹双引号即可。最直接的处理方法:使用条件分支判断数据类型,代码实现为:

对于 Number / Boolean 可以直接使用toString(),对于null则需要直接返回'null'字符串。以上就是所有实现,但是类型判断处代码使用了较深的if分支判断,可以继续优化,而且没有考虑数据合法性校验的问题,待更新。另注意,JSON 中是没有undefined这种数据类型的。

注:转载注明出处并联系作者,本文链接:https://nodefe.com/implementation-of-stringify/

发表评论

评论

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax