js处理Json中的长整数

26. 10 月 2017 JavaScript 0

在前端页面展示数据的时候,通常都需要处理来自后端的json数据。通常这个过程都是非常简单的,比如通过jQuery的ajax(或者更暴力的getJSON)。但是如果服务器传来的json中包含一个很大的整数,如 {"v": 123456789123456789123} ,那么接受后会发现变成了 {v: 123456789123456800000} 。

问题原因

js是弱类型语言,所有的数字类型统称为Number类型,不区分int、long、double等。而Number是根据IEEE 754的double来实现的,即所有的Number类型都是64位双精度实型。sf上提供了一个对IEEE 574非常友好的讲解,这里不再赘述。在文章中也提到了NUMBER.MAX_SAFE_INTEGER的计算方法,是9007199254740991,所有大于这个数的整数都会损失精度。

可行的解决方案

  1. 最直接的,让服务端传数据的时候,把超长的字段强转成string。但是如果服务端类型敏感,且比较复杂的时候,通常不太想这么搞。
  2. 前端实现一个json parser。

制作json parser

在服务端开发中,通常使用bison可以定制json parser(在fp中则更简单),js中有没有类似bison的工具呢?有——jison,号称“bison in javascript”,通过npm可以安装,不过他的文档地址似乎不太对,需要访问这里。好在功能上用起来还是没啥问题的。

npm install jison 之后,在 lib 目录下提供了 cli.js 来生成我们的parser。参数有两个(通常情况,有很多我们不太需要,详见cli.js代码), cli.js grammaFile lexFile ,grammaFile是语法文件,lexFile是词表文件。

下面就是怎么写这两个文件了,可以通过文档来学习一下这类文件的语法。如果不想这么麻烦,还可以在jison作者的另一个项目——jsonlint里面找到,在该项目github中的src目录下提供了jsonlint.y(grammaFile)和jsonlint.l(lexFile)。使用这两个文件可以直接生成jsonlint.js,放