js便簽筆記(10) - 分享: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-\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源碼過程中做的一點隨意的筆記,列出來跟大家分享。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM