JSON.stringify
您可以向and提供自定义 JSON 解析器/字符串化器JSON.parse
:
var serialized = JSON.stringify(obj, /*func*/replacer);
var deserialized = JSON.parse(serialized, /*func*/reviver);
除了自定义 reviver 之外,您还可以toJSON
在将要序列化的对象上定义一个方法。此方法接收一个参数:数组中键的名称索引、对象中的属性名称(如果适用)。
// Examples of a serializing a function
var dummyFunction = function() {return 'hey';};
Function.prototype.toJSON = function(key) {
'use strict';
return this.toString();
};
JSON.stringify(dummyFunction);
// Method 2:
var replacer = function(/*string*/key, /*any*/value, /*boolean*/pretty_print) {
if (typeof value == 'function') return value.toString();
return value;
};
JSON.stringify(dummyFunction, replacer);
// >>> "function () {\n return \"hey\";\n}"
// Result of the previous, stored in a variable
var result = '"function () {\\n return \\"hey\\";\\n}"';
// Reviver example
// Note: Just an example. Do not use it without modification in production code,
// Because the pattern can easily be misguided: "function(){}alert('Evil');x={}"
// Even if you do not mind, at least add a try-catch block inside
// `if (func)`, so that a malformed function does not break the reviver
JSON.parse(result, function(/*string*/key, /*string*/value) {
var func = /^\s*function\s*\(([^)]*)\)\s\{([\S\s]*)}$/.exec(value);
if (func) {
// Note: Function( .. ) is equivalent to new Function( .. )
var args = func[1].match(/[^,\s]+/g); // <-- Parameters
// Function body:
if (args === null) args = [func[2]];
else args.unshift(func[2]);
return Function.apply(null, args);
}
return value;
});
这是本机解析与使用 reviver 解析的 JSPerf 比较:http: //jsperf.com/json-reviver。它表明,没有什么特别功能的自定义 reviver 速度要慢两倍,而具有昂贵功能的 reviver 则要慢得多。
但是,当将最后一种方法与使用原生 JSON 和“手动转换”的较弱方法进行比较时,差异似乎被忽略了。
注意:仅对单个值进行了基准测试。确保为您自己的(特定)案例创建自定义基准,因为不可能创建一个代表所有可能案例的基准。
我创建了一个JSPerf 测试用例来检查.toJSON
. 为了隔离噪音,我创建了一个基于Date
对象的测试用例。具有多个函数调用的自定义函数仅比原生函数慢两倍Date.prototype.toJSON
。