其實,之前我一直以為 JSON 會把 ASCII 可顯示字符以外的統統轉義為 Unicode,
直到有一次我用 JSON.stringify 才發現,其實是 PHP 為我們想的太周到了。
我以前是一位 phper,所以處理 json 只要 json_encode 就可以把數組轉為 json 數據了,非常方便。
可以看到,默認就是把所有 ASCII 可顯示字符以外的統統轉義為 Unicode。
這樣做有什么好處呢?
大家在調用 jsonp 接口或者調用js文件的時候,由於文件編碼不同導致的亂碼問題,應該不會陌生吧。
如果你的文件出現了非英文字符,如果調用時文件編碼不一致,則會出現亂碼情況。
很多新手朋友應該都糾結過這種問題吧。
但是如果把那些字符轉義為 Unicode 之后,無論文件編碼是否一致,都不會出現亂碼。
這就是為什么 PHP 會默認編碼為 Unicode 的原因,她為我們想的太周到了。
當然如果你非要直接顯示那些字符,也是OK的,第二個參數加上 JSON_UNESCAPED_UNICODE 即可。
但是這個參數 PHP 5.4.0 才開始支持。
那么 JSON.stringify 會轉義哪些呢?
在 json2.js 第 351 行可以看到這個正則。
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
也就是說 JSON 只會轉義這部分字符為 unicode,我們來簡單測試下吧。
console.log( JSON.stringify("\x00 \x0a") );
點運行后,可以看到 \x00 被轉義為 \u0000 而 \x0a 卻被專為了 \n
像 \n 這些特殊字符的轉換在剛才那個正則下面就可以看到了。
但是你測試字符 \ufeff 的時候會發現 firefox 和 chrome 根本沒轉義。
確實,,好像只有 json2 為我們轉義了。
為什么原生 JSON.stringify 這么多字符都沒轉義,難道他就沒為我們考慮兼容問題么?
其實我覺得,這個問題可以不要考慮,因為你不會直用靜態的頁面為其他站點提供接口之類的。
往往只是自己內部用而已,就算提交給后台,一個項目下編碼也是一樣的,所以內部不需要考慮那些兼容問題。
就好比在自己老家,難道你要普通話或英文跟他們交流么?
直接用方言交流才更加流暢。
當然這個只是我個人觀點,也不知道寫js引擎的大神是怎么想的。
我們來遍歷下原生 JSON 對 \u000-\uffff 這些字符的轉義情況吧。
for (var i = 0, str = '', arr = []; i < 0xffff; i++) { str = JSON.stringify(String.fromCharCode(i)); str.indexOf("\\") > -1 && arr.push(str); } console.log(arr.join(", "));
我的 chrome 34 得到的結果是
["\u0000", "\u0001", "\u0002", "\u0003", "\u0004", "\u0005", "\u0006", "\u0007", "\b", "\t", "\n", "\u000b", "\f", "\r", "\u000e", "\u000f", "\u0010", "\u0011", "\u0012", "\u0013", "\u0014", "\u0015", "\u0016", "\u0017", "\u0018", "\u0019", "\u001a", "\u001b", "\u001c", "\u001d", "\u001e", "\u001f", "\"", "\\"];
好了,今天的分享就這些了。