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. (转)WCF中神秘的“8733"端口和“Design_Time_Addresses”

    转自:http://blog.csdn.net/bitfan/article/details/4193319 如果使用Visual Studio 2008 SP1开发WCF应用程序时,会发现当使用Vi ...

  2. 原生JS一些操作

    很久没写原生的JS了,上周做了一个小东西让我又重新了解了一下原生JS,以下记录一些常见的原生JS var canvArrow = document.getElementById('js-canv_ar ...

  3. (day20)javaEE三大组件之一Servlet (简介(二)servletconfig,servletContext,session,cookie,request,response,out)

    javaEE是服务器编程,javaEE提供了服务器的接口让具体的服务器去创建实现的对象 JavaEE是sun公司为了解决企业级开发定义的一套技术,只提供了规范,具体的实现是由服务器完成的 servle ...

  4. Hdu4687 Boke and Tsukkomi

    Boke and Tsukkomi                                                                               Time ...

  5. poj 2192 Zipper

    题目 刚开始本来觉得可以用队列来写,但是 例如 ta te teta,ta的t先出队列那就不行了,所以还得用dp dp[i][j] 表示A前i个字符与B前j个字符是否能构成C前i+j个字符 要使 dp ...

  6. AngularJS 控制器 Live Dom

    控制器的作用是在$scope对象上创建属性和方法,控制器的作用域是$scope,所以作用域是针对控制器来讲的.另外,控制器实例不是单例,每次都会重新实例化,不像服务是单例的. 其是注册在模块上的,如 ...

  7. 【转】C# 之泛型详解

    原文地址:https://www.cnblogs.com/yueyue184/p/5032156.html 什么是泛型 我们在编写程序时,经常遇到两个模块的功能非常相似,只是一个是处理int数据,另一 ...

  8. JavaScript基础(3)-JS中的面向对象、定时器、BOM、位置信息

    一.创建对象的几种常用方式. 1.使用Object或对象字面量创建对象: a.使用Object()内置的构造函数来创建对象,例如: var student = new Object(); // 创建一 ...

  9. python收集jvm数据

    之前前辈用 java 写的收集 jvm 脚本, 不太方便组内小伙伴维护, 遂用 python 重写了 #!/usr/bin/env python # -*- coding: utf-8 -*- # F ...

  10. CentOS 7 下网络管理

    如果最小化安装centos7  后会发现,安装完了进去配置网络发现,ifup ,ipconfig 这些命令不见了,那是因为 7 使用了新的网络管理工具NetworkManager ,具体的命令是nmc ...