前言:对于简单的数据结构而言,我们经常使用JSON.parse()、JSON.stringify()进行拷贝,但它无法实现Function类型的拷贝,我们可以使用JSON.stringify()的可选参数实现
概念
语法
JSON.stringify(value[, replacer [, space]])
参数
- 【value】 将要序列化成 一个 JSON 字符串的值。
- 【replacer 可选】如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
- 【space 可选】指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
代码实现
const parser = {
FUNC_PREFIX: "__customFunc__",
isArrOrObj: function (obj) {
return !!obj && typeof obj === "object";
},
funcParse: function (obj) {
let result = obj.constructor === Array ? [] : {};
if (obj.constructor === Array) {
result = obj.map((v) => {
/** 如果是函数类型, 则转换为字符串 */
if (typeof v === "function") {
return `${this.FUNC_PREFIX}${v}`;
}
/** 如果是数组或者对象 */
if (this.isArrOrObj(v)) {
return this.funcParse(v);
}
/** 基本类型 */
return v;
});
}
if (obj.constructor === Object) {
for (let key in obj) {
const v = obj[key];
if (typeof v === "function") {
result[key] = `${this.FUNC_PREFIX}${v}`;
} else if (this.isArrOrObj(v)) {
result[key] = this.funcParse(v);
} else {
result[key] = v;
}
}
}
return result
},
parse:function(jsonStr,error=new Error) {
try {
return JSON.parse(jsonStr,(key,value)=>{
if(value && typeof value === 'string') {
return value.indexOf(this.FUNC_PREFIX) > -1 ? new Function(`return ${value.replace(this.FUNC_PREFIX,'')}`)():value
}
return value
})
}catch(err) {
error && error(err)
}
},
stringify:function(obj,replacer=null,space=null,error = new Error){
try{
let _obj = obj
if(this.isArrOrObj(obj)) {
_obj = this.funcParse(obj)
}
if(typeof obj === 'function') {
_obj = `${this.FUNC_PREFIX}${obj}`
}
return JSON.stringify(_obj,replacer,space)
}catch(err) {
error && error(err)
}
},
fastStringify:function(obj,space=null,error=new Error) {
try {
return JSON.stringify(obj,(key,value)=>{
if(typeof value === 'function') {
return `${this.FUNC_PREFIX}${value}`
}
return value
},space)
}catch(err) {
error && error(err)
}
}
};
网友评论