1. 如何理解“json”

首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西。它不是js对象,也不是字符串,它只是一种格式,一种规定而已。

这个格式规定了如何将js对象转换成字符串、以及转换成怎样的字符串——序列化 —— JSON.stringify 接口;

以及如何将一个有效字符串转换成js对象——反序列化—— JSON.parse 接口;

2. 关于作者

json作者是 道格拉斯.克劳福德 ,是一位js大牛,写过一本《javascript语言精粹》,相信不少朋友都看过。短短200页书,果然写出了“精粹”。

3. 浏览器支持

W3C已经将json接口定义到标准中,目前主流浏览器也都默认支持json接口。但是还有不少IE6用户,可得小心。我曾经遇到过这样的bug。

4. valueOf() 的用法

var n1 = 10;
var n2 = new Number(10);
console.log(typeof n1); //number
console.log(typeof n2); //object
console.log(typeof n2.valueOf()); //number

如上代码,通过valueOf()方法,可以将一个(Number/String/Boolean)对象,转换成其对应的基本类型。

在json.stringify方法中,如果遇到一个属性值的类型是object时,首先要排除 new Number/String/Boolean(...) 这三种情况,它就是通过valueOf来操作的。

5. 对特殊字符的处理

json.js源码中考虑了一些无意义的unicode字符,并且对他们进行了自定义的处理。相关的正则表达式如下:

escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;

这两个正则表达式,分别用在stringify和parse方法中。可以用图形形象表达这两个正则的内容,如下图:

因此,解读json.js源码,还必须了解unicode字符集的基础知识。

6. 在遇到Date类型或者Number类型时,都不要忘记用 isFinite()来验证有效性。

7. JSON.parse() 对传入字符串的验证

大家用JSON.parse(),而不直接用eval()的原因,就是因为前者是安全转换。那么这里的“安全”是通过什么来保障的呢?

源码中通过四步验证来保证。下面是这四步验证,以及我写的注释:

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we // 01. 将反斜线格式变为“@”,如把'\\n'变为'@'
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we // 02. 将简单值替换为“]”
// replace all simple value tokens with ']' characters. Third, we delete all // 03. 将“: [”、“, [”替换为空字符串
// open brackets that follow a colon or comma or that begin the text. Finally, // 04. 看剩下的字符串是否只是 whitespace or ']' or ',' or ':' or '{' or '}'
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. // 如果是这样,那么text就可以安全的被执行eval()函数 if (/^[\],:{}\s]*$/ //只包含 whitespace or ']' or ',' or ':' or '{' or '}'
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') // 例如:'\\n'->'@','\\u4e00'-> '@',而'\n','\u4e00'则不变
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') // 将 "abc"、true、false、null、数字,替换成“]”
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {...}

8. JSON.stringify(value, replacer, space) 第二个参数可以传伪数组

大家可能知道第二个参数replacer可以传入function或者Array,但是它也可以传如一个伪数组,模拟传入Array的情况。伪数组要这样写:

{
0 : 'a',
1 : 'b',
2 : 'x',
length : 3
}

不过注意!浏览器中自带的JSON接口,不一定支持,例如chrome中就不识别。所以这里要谨慎使用。安全期间还是用标准的Array好一些。

9. 两个JS基础知识

第一,value 是数组时,注意 Object.prototype.toString.apply(value) 和 value.toString() 的区别;

第二,在 for ... in 循环中,要判断 Object.prototype.hasOwnProperty.call(value, k)

不解释,看不明白的需要去翻书。

--------------------------------------------------------------------------

json2.js源码解读教程

PetShop4.0源码解读

---------------------------------------------------------------------------

10. 总结

以上是我在解读json2.js源码过程中做的一点随意的笔记,列出来跟大家分享。

js便签笔记(10) - 分享:json2.js源码解读笔记的更多相关文章

  1. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  2. jquery.fileupload源码解读笔记

    基础编程风格 新建 test.html  和 test.js和 main.js和 无论哪种顺序 <body> <script src="/Sandeep/js/jquery ...

  3. ArrayList源码解读笔记

    简介: ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高. 线 ...

  4. Entity Framework 6.0 源码解读笔记(一)

    internal static TResult ExecuteSingle<TResult>(IEnumerable<TResult> query, Expression qu ...

  5. Rafy源码解读 笔记(一) DbMigration

    主要功能,提供数据库的升级回滚和变迁操作. 整个模块的都是通过DbMigrationContext这个类来体现的,回滚或升级由若干个子操作完成,每个子操作被封装成一个类MigrationOperati ...

  6. springMVC源码解读笔记

    1: DispatcherServlet 的初始化流程(调用的init方法) a) 初始化spring高级容器,WebApplicationContext(容器初始化12个步骤) Servlet类的i ...

  7. js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

    1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭 ...

  8. js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)

    1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...

  9. js便签笔记(14)——用nodejs搭建最简单、轻量化的http server

    1. 引言 前端程序猿主要关注的是页面,你可能根本就用不到.net,java,php等后台语言. 但是你制作出来的网页总要运行.总要测试吧?——那就免不了用到http server.我先前都是用vis ...

随机推荐

  1. (01背包 第k优解) Bone Collector II(hdu 2639)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639       Problem Description The title of this problem i ...

  2. java基础-day21

    第10天  IO流 今日内容介绍 u  标准输入流 & 转换流 & 打印流 u  对象操作流 u  Properties集合 第1章   标准输入流 & 转换流 & 打 ...

  3. 入手IntelliJ IDEA 常用配置

    Idea常用设置 下载地址:https://www.jetbrains.com/idea/ 激活服务器:http://idea.iteblog.com/key.php 代码补全取消区分大小写 Inte ...

  4. codeforces 982 c

    给你一棵树 让你进行切割 问你最多能切多少刀   使得每个连通分量size都是偶数 思路:首先  要是有奇数个节点的话   那么不管你怎么切割  都会有一个连通分量的size是奇数 所以只有偶数的情况 ...

  5. hdu 4135 [a,b]中n互质数个数+容斥

    http://acm.hdu.edu.cn/showproblem.php?pid=4135 给定一个数n,求某个区间[a,b]内有多少数与这个数互质. 对于一个给定的区间,我们如果能够求出这个区间内 ...

  6. shell 命令 查看本机ip

    ifconfig 结果有很多,查看env0的inet,就是本机的ip地址

  7. mysql数据导入导出方法总结

    MySQL数据备份还原方式总结: 一.将数据导入到指定的数据库 第一种导入方式: (linux下和Windows 下语法是一样的,只是路径的书写方式不同而已) 1.创建一个空数据库 2.进入MySQL ...

  8. Windows 下环境变量设置(命令行)

    0. 背景 查了一下 SETX 命令可以实现,先简单看了下帮助.以后再写一个实例. 1. SETX /?    输出内容: SetX 有三种使用方式: 语法 1: SETX [/S system [/ ...

  9. tfs查看最近签入记录及文件

    在团队资源管理=>源代码管理资源管理器=>选择某个最近签入的文件夹=>右键=>查看历史记录=>双击某个文件夹 就能看到最近变更集文件

  10. SignalR2结合ujtopo实现拓扑图动态变化

    上一篇文章基于jTopo的拓扑图设计工具库ujtopo,介绍了拓扑设计工具,这一篇我们使用SignalR2结合ujtopo实现拓扑图的动态变化. 仅仅作为演示,之前的文章SignalR2简易数据看板演 ...