<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script type="text/javascript">
var JSON;
if (!JSON) {
JSON = {};
} (function () {
'use strict'; function f(n) {
// Format integers to have at least two digits.
// 补齐 两位数
return n < 10 ? '0' + n : n;
}
  
// 在高级浏览器调用
    (new Date() ).toJSON()
    "2017-07-28T01:27:34.790Z" , 所以下面是按照这个格式来模拟 if (typeof Date.prototype.toJSON !== 'function') { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf())
? this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z'
: null;
};
    
     //不支持toJSON 的浏览器可以取这些元素对象的 值
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
  
  //过滤掉unicode特殊字符,
   可以通过String.fromCharCode(parseInt(unicode),16)来输出,不过大部分unicode是『不可见』的,还是要通过unicode码表来查看
    text.replace(/\\u[\dA-F]{4}/gi, function (match) { return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16)); }); var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
     //一些讨厌的特殊字符
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions 字符替换表格, 一些需要转义
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep; function quote(string) { // If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
    
// 如果字符串包涵了 控制字符? 引号, 反斜杠, 我们就必须把这些讨厌的字符给替换成安全的, 否则我们把这些用引号给包裹起来,
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string'
? c
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
} function str(key, holder) { // Produce a string from holder[key]. var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value.
// 如果有toJSON方法, 调用生成序列化字符串 if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
} // If we were called with a replacer function, then call the replacer to
// obtain a replacement value. 如有有替代的函数 if (typeof rep === 'function') {
value = rep.call(holder, key, value);
} // What happens next depends on the value's type. vule的类型决定下一步干什么 switch (typeof value) {
case 'string':
return quote(value); case 'number': // JSON numbers must be finite. Encode non-finite numbers as null. 如果无限的值被转成 null return isFinite(value) ? String(value) : 'null'; case 'boolean':
case 'null': // If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
// 如果值是 boolean null, 转成 'true' 'false' 'null'; 虽然typeof null 不会是‘null’ , 但以后有机会被修正成'null', 所以这里我们也把这种情况包含进来 return String(value); // If the type is 'object', we might be dealing with an object or an array or
// null. case 'object': // Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case. if (!value) {
return 'null';
} // Make an array to hold the partial results of stringifying this object value.
// 用一个数组保存部分已被序列化的结果
gap += indent;
partial = []; // Is the value an array? if (Object.prototype.toString.apply(value) === '[object Array]') { // The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values. length = value.length;
for (i = 0; i < length; i += 1) {
//如果数组, 递归调用str
partial[i] = str(i, value) || 'null';
} // Join all of the elements together, separated with commas, and wrap them in
// brackets. 组合所有的元素以前, 用逗号分隔, 用括号包裹 v = partial.length === 0
? '[]'
: gap
? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
: '[' + partial.join(',') + ']';
gap = mind;
return v;
} // If the replacer is an array, use it to select the members to be stringified. if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else { // Otherwise, iterate through all of the keys in the object. for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} // Join all of the member texts together, separated with commas,
// and wrap them in braces. v = partial.length === 0
? '{}'
: gap
? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
: '{' + partial.join(',') + '}';
gap = mind;
return v;
}
} // If the JSON object does not yet have a stringify method, give it one. if (typeof JSON.stringify !== 'function'||(navigator.userAgent.indexOf("MSIE 8.0")>0)) {
JSON.stringify = function (value, replacer, space) { // The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable. var i;
gap = '';
indent = ''; // If the space parameter is a number, make an indent string containing that
// many spaces. if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
} // If the space parameter is a string, it will be used as the indent string. } else if (typeof space === 'string') {
indent = space;
} // If there is a replacer, it must be a function or an array.
// Otherwise, throw an error. rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
} // Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value. return str('', {'': value});
};
} // If the JSON object does not yet have a parse method, give it one. if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) { // The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text. var j; function walk(holder, key) { // The walk method is used to recursively walk the resulting structure so
// that modifications can be made. var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
} // Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings. text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
} // In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms. // 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
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// 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.      //先把无意义的 字符替换成空, 在看看结果是不是符合JSON格式
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { // In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity. j = eval('(' + text + ')'); // In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation. return typeof reviver === 'function'
? walk({'': j}, '')
: j;
} // If the text is not JSON parseable, then a SyntaxError is thrown. throw new SyntaxError('JSON.parse');
};
}
}()); </script> </body>
</html>

JSON.js 源码学习..的更多相关文章

  1. Underscore.js 源码学习笔记(上)

    版本 Underscore.js 1.9.1 一共 1693 行.注释我就删了,太长了… 整体是一个 (function() {...}());  这样的东西,我们应该知道这是一个 IIFE(立即执行 ...

  2. Underscore.js 源码学习笔记(下)

    上接 Underscore.js 源码学习笔记(上) === 756 行开始 函数部分. var executeBound = function(sourceFunc, boundFunc, cont ...

  3. js便签笔记(10) - 分享:json.js源码解读笔记

    1. 如何理解“json” 首先应该意识到,json是一种数据转换格式,既然是个“格式”,就是个抽象的东西.它不是js对象,也不是字符串,它只是一种格式,一种规定而已. 这个格式规定了如何将js对象转 ...

  4. Vue.js 源码学习笔记

    最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...

  5. vue.js源码学习分享(一)

    今天看了vue.js源码  发现非常不错,想一边看一遍写博客和大家分享 /** * Convert a value to a string that is actually rendered. *转换 ...

  6. AlloyTouch.js 源码 学习笔记及原理说明

    alloyTouch这个库其实可以做很多事的, 比较抽象, 需要我们用户好好的思考作者提供的实例属性和一些回调方法(touchStart, change, touchMove, pressMove, ...

  7. move.js 源码 学习笔记

    源码笔记: /* move.js * @author:flfwzgl https://github.com/flfwzgl * @copyright: MIT license * Sorrow.X - ...

  8. lazy-load-img.js 源码 学习笔记及原理说明

    lazy-load-img.js? 1. 什么鬼? 一个轻量级的图片懒加载,我个人很是喜欢. 2. 有什么优势? 1.原生js开发,不依赖任何框架或库 2.支持将各种宽高不一致的图片,自动剪切成默认图 ...

  9. AlloyFinger.js 源码 学习笔记及原理说明

    此手势库利用了手机端touchstart, touchmove, touchend, touchcancel原生事件模拟出了 rotate  touchStart  multipointStart   ...

随机推荐

  1. 蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现

           蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现        尽管蓝牙4.0 BLE芯片CC2540 是单芯片(即用户能够对它进行芯片级代码编写), 是80 ...

  2. 前端页面汉子显示为问号,需修改 linux下面修改mysql 数据库的字符编码为utf8

    设置MySQL数据库编码为UTF-8 登陆后查看数据库当前编码:SHOW VARIABLES LIKE 'char%'; 修改/etc/mysql/my.cnf (默认安装路径下) (标签下没有的添加 ...

  3. Check out our list of adidas NMD Singapore retailers

    The adidas NMD Singapore is confirmed to produce on The month of january 14th at select adidas Origi ...

  4. 2.6 The Object Model -- Bindings

    一个binding在两个属性之间创建一个链接,当一个改变时,另外一个被自动更新为一个新的值. bindings可以在同一个对象中连接两个属性,或者用在两个不同的对象中. 不像大多数框架一样包含某种形式 ...

  5. SpringData环境搭建代码编写

    首先我们在前面的两节已经了解了SpringData是干什么用的?那我们从这节开始我们就开始编码测试SpringData. 1:首先我们从配置文件开始,我们首先需要写一个连接数据库的文件db.prope ...

  6. 1linux的基本命令

    查看命令的帮助信息man 命令名 文件操作touch 建立文件 (对于已存在文件,更新时间)cat 查看文件 (-n 自动加上行号)rm 删除文件cp 拷贝文件mv 移动/重命名文件more 分页查看 ...

  7. uva1452

    这题说的是给了一个序列1到n然后你从1 位置开始数k个删除,直到最后每个数都被删除了.我们考虑1个数在被删除前后的位置,比如现在在i位置那么 回到删除当前的最后一个是 (i+k)L 了为删除前 的 个 ...

  8. maven nexus私服搭建

    1. 下载 wget http://download.sonatype.com/nexus/oss/nexus-2.12.0-01-bundle.tar.gz 2. 解压 tar zxvf nexus ...

  9. 同样的输入,为什么Objects.hash()方法返回的hash值每次不一样?

    背景 开发过程中发现一个问题,项目中用Set保存AopMethod对象用于去重,但是发现即使往set中添加相同内容的对象,每次也能够添加成功. AopMethod类的部分代码如下: public cl ...

  10. HDU 5934 Bomb(tarjan/SCC缩点)题解

    思路:建一个有向图,指向能引爆对象,把强连通分量缩成一点,只要点燃图中入度为0的点即可.因为入度为0没人能引爆,不为0可以由别人引爆. 思路很简单,但是早上写的一直错,改了半天了,推倒重来才过了... ...