js便签笔记(10) - 分享:json.js源码解读笔记
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)
不解释,看不明白的需要去翻书。
10. 总结
以上是我在解读json2.js源码过程中做的一点随意的笔记,列出来跟大家分享。最后贴出我录制的json.js源码解读教程,欢迎去看看!
--------------------------------------------------------------------------
json2.js源码解读教程
---------------------------------------------------------------------------
js便签笔记(10) - 分享:json.js源码解读笔记的更多相关文章
- js便签笔记(10) - 分享:json2.js源码解读笔记
1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...
- jquery.fileupload源码解读笔记
基础编程风格 新建 test.html 和 test.js和 main.js和 无论哪种顺序 <body> <script src="/Sandeep/js/jquery ...
- ArrayList源码解读笔记
简介: ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高. 线 ...
- springMVC源码解读笔记
1: DispatcherServlet 的初始化流程(调用的init方法) a) 初始化spring高级容器,WebApplicationContext(容器初始化12个步骤) Servlet类的i ...
- Entity Framework 6.0 源码解读笔记(一)
internal static TResult ExecuteSingle<TResult>(IEnumerable<TResult> query, Expression qu ...
- Rafy源码解读 笔记(一) DbMigration
主要功能,提供数据库的升级回滚和变迁操作. 整个模块的都是通过DbMigrationContext这个类来体现的,回滚或升级由若干个子操作完成,每个子操作被封装成一个类MigrationOperati ...
- js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2
1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭 ...
- js便签笔记(2)——DOM元素的特性(Attribute)和属性(Property)
1.介绍: 上篇js便签笔记http://www.cnblogs.com/wangfupeng1988/p/3626300.html最后提到了dom元素的Attribute和Property,本文简单 ...
- js便签笔记(14)——用nodejs搭建最简单、轻量化的http server
1. 引言 前端程序猿主要关注的是页面,你可能根本就用不到.net,java,php等后台语言. 但是你制作出来的网页总要运行.总要测试吧?——那就免不了用到http server.我先前都是用vis ...
随机推荐
- The file left unchanged.
This files have types: *.___jb_old___ and *.___jb_bak___ The file left unchanged. You can disable &q ...
- java中JDK环境变量的配置
JDK的配置在 window中的配置,我的电脑-->属性-->高级系统设置-->高级-->环境变量中配置,具体下图
- LCA的 RMQ解法模版
struct Edge{ int from, to, nex; }edge[N<<1]; int head[N], edgenum; void addedge(int u, int v){ ...
- Android-Java-同步方法-synchronized
1.方法具有封装性: /** * 1.方法具有封装性: */ public void addMoney(double moneyAsset) { this.moneyAsset += moneyAss ...
- 解决toad中number类型小数位数过长按科学计数法显示的问题
在toad中->view->option->data->display large number in scientific notation,不选择该选项即可. (在pl/s ...
- 【Unity】UGUI系列教程——拼接一个简单界面
0.简介: 在目前的游戏市场上,手游依然是市场上的主力军,而只有快速上线,玩法系统完善的游戏才能在国内市场中占据份额.而在手游开发过程中,搭建UI系统是非常基本且重要的技能,极端的说如果对Unity的 ...
- WPF 内存泄漏优化经历
最近公司有个CS客户端程序,有个登录界面,有个程序的主界面,程序支持注销功能,但是在注销后,客户端的内存一直以40M-50M的速度递增,因此猜测,应该是WPF程序出现了内存泄漏.下面主要记录优化内存泄 ...
- InfluxDB 安装以及使用
InfluxDB InfluxDB简介: InfluxDB 是一个开源分布式时序.事件和指标数据库.使用Go语言编写,无需外部依赖.其设计目标是实现分布式和水平伸缩扩展. 它有三大特性: ...
- 【转】C#模拟http 发送post或get请求
原文地址:http://www.cnblogs.com/xssxss/archive/2012/07/03/2574554.html 模拟POST Json public static string ...
- Lerning Entity Framework 6 ------ Introduction to TPT
Sometimes, you've created a table for example named Person. Just then, you want to add some extra in ...