分享:json2.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-x1fx7f-x9fu00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g;
cx = /[u0000u00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-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'-> '@',而'
','u4e00'则不变
                        .replace(/"[^"\

]*"|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源代码过程中做的一点任意的笔记,列出来跟大家分享。广告时间:

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

json2.js源代码解读教程

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

原文地址:https://www.cnblogs.com/mengfanrong/p/3864147.html