分享: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)
不解释,看不明确的须要去翻书。
10. 总结
以上是我在解读json2.js源代码过程中做的一点任意的笔记,列出来跟大家分享。广告时间:
--------------------------------------------------------------------------
json2.js源代码解读教程
---------------------------------------------------------------------------
分享:json2.js源代码解读笔记的更多相关文章
- vue.js 源代码学习笔记 ----- html-parse.js
/** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...
- vue.js 源代码学习笔记 ----- 工具方法 share
/* @flow */ /** * Convert a value to a string that is actually rendered. { .. } [ .. ] 2 => '' */ ...
- vue.js 源代码学习笔记 ----- 工具方法 lang
/* @flow */ // Object.freeze 使得这个对象不能增加属性, 修改属性, 这样就保证了这个对象在任何时候都是空的 export const emptyObject = Obje ...
- vue.js 源代码学习笔记 ----- 工具方法 env
/* @flow */ /* globals MutationObserver */ import { noop } from 'shared/util' // can we use __proto_ ...
- jquery.sortable.js源代码解读
/* * HTML5 Sortable jQuery Plugin * http://farhadi.ir/projects/html5sortable * * Copyright 2012, Ali ...
- vue.js 源代码学习笔记 ----- helpers.js
/* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...
- vue.js 源代码学习笔记 ----- codegenEvents.js
/* @flow */ const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/ const simplePathRE = / ...
- vue.js 源代码学习笔记 ----- codegen.js
/* @flow */ import { genHandlers } from './events' import { baseWarn, pluckModuleFunction } from '.. ...
- vue.js 源代码学习笔记 ----- decoder
/* @flow */ let decoder export function decode (html: string): string { decoder = decoder || documen ...
随机推荐
- Python正则表达式一: 基本使用方法
学习python的正则表达式,主要有两个方面学习: 第一,学习如何写正则表达式,主要是掌握其语法规范.正则表达式的语法规范是通用的,对各种开发语言都是一致的. 第二,学习如何使用正则表达式,也就是掌握 ...
- Spring Boot Memory Performance
The Performance Zone is brought to you in partnership with New Relic. Quickly learn how to use Docke ...
- IPTABLES 映射问题
今天要做一个新的映射:将内网的一个8090口映射到外网的8087口. 在 /ETC/RC.LOCAL中最后插入: iptables -t nat -A PREROUTING -d outIP -p t ...
- 制作cdlinux u盘启动
U盘一个 CDlinux的iso镜像文件 UltraISO grub4dos grubinst 方法/步骤1 1 [第一步]:用UltraISO把CDlinux的镜像刻录进U盘. 打开UltraISO ...
- 搜狗2015校园招聘javaproject师面经
面试时看到了我的笔试题.真是慘不忍睹啊. . 1. 问回去有没有研究一下笔试题 木有,果断后面悲剧了 2. 解释一下笔试的一道选择题: 下列哪种操作可能带来死锁? A: lock(m1) lock(m ...
- android中使用jni对字符串加解密实现分析
android中使用jni对字符串加解密实现分析 近期项目有个需求.就是要对用户的敏感信息进行加密处理,比方用户的账户password,手机号等私密信息.在java中,就对字符串的加解密我们能够使用A ...
- objective-C学习笔记(二)类 class 和 结构 struct
Objective-C的类型 引用类型 类 class 指针 pointer 块 block 值类型 基础数值类型 结构 struct 枚举 enum 类型装饰 协议 protocol 类别 cate ...
- linux命令:rsync, 同步文件和文件夹的命令
Usage: rsync [OPTION]... SRC [SRC]... DEST or rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST or ...
- NOIP2015酱油记
day0 坐动车到广州..下午就在酒店颓... day1 早上6:30起床...大概8:00到六中..ZSJZ众貌似很晚才到..毕竟他们酒店就在学校门口(真的就刚刚好是门口...),大概8:15进去机 ...
- C/C++用strncpy()与strstr()分割与匹配查找字符串
最近做题遇到分割与匹配字符串的题目(hdu5311),看来别人的代码,才知道有strncpy()和strstr()函数,于是搜集了一点资料,记录一下基本用法. 一.strncpy() char * s ...