JSON.stringify()和JSON.parse()不能转换RegExp的问题

前言

有一个Json对象如{"name": 'admin', "pattern": /^[0-9]+$/},用JSON.stringify()转成Json字符串的时候发现转成了"{"name":"admin","pattern":{}}",把正则对象转成了空对象。以至于调用JSON.parse()时,把这条正则数据给丢失了。

原因

JSON.stringify会处理的几种类型: String, Number, Boolean, null, Array, Object
不会处理的几种类型: Date, RegExp, undefined, Function

var o = {
    n: 1,
    s: 'abc',
    b: true,
    empty: null,
    a: [1,2,3],
    o:{ a: 1},
    d: new Date(),
    r: /abc/,
    u: undefined,
    f: function(){}
}

console.log(JSON.stringify(o));
// {"n":1,"s":"abc","b":true,"empty":null,"a":[1,2,3],"o":{"a":1},"d":"2018-07-05T02:49:37.194Z","r":{}}

可以看到,支持的类型都被处理了; 不支持的类型中,Date类型被转成了字符串输出,正则表达式转成了空对象, undefinedFunction都被直接忽略了。

解决

用到JSON.stringify方法中的第二个可选参数 replacer

如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 Json 字符串中;如果该参数为null或者未提供,则对象所有的属性都会被序列化;

对于JSON.stringify不支持的数据类型,推荐使用replacer来处理。

JSON.stringify({r: /abc/}, function(k, v){
    if(v instanceof RegExp){
        return v.toString();
    }
    return v;
});
// '{"r":"/abc/"}'

同理,要将带有正则字符串的Json字符串解析成Json对象的时候,也要讲不支持转换的类型做处理,也要用到JSON.parse的第二个参数。

JSON.parse(text[, reviver])

text:必需, 一个有效的 JSON 字符串。
reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。

如:

JSON.parse('{"p": 5}', function(k, v) {
  if (k === '') { return v; } 
  return v * 2;               
});                          
 
JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', function(k, v) {
  console.log(k); // 输出当前属性,最后一个为 ""
  return v;       // 返回修改的值
});

最后

附一个工具类

/**
 * 解决JSON.stringify和JSON.parse不能转换RegExp的问题
 * @author Junan
 * @see JSON.parse();JSON.stringify()
 */

/**
 * json字符串转json对象
 * @param { String } jsonStr json字符串
 */
export function parseJson(jsonStr){
  return JSON.parse(jsonStr, (k, v) => {
    try{
      // 将正则字符串转成正则对象
      if (eval(v) instanceof RegExp) {
        return eval(v);
      }
    }catch(e){
      // nothing
    }

    return v;
  });
}

/**
 * json对象转json字符串
 * @param { Object } json json对象
 */
export function stringifyJson(json){
  return JSON.stringify(json, (k, v) => {
    // 将正则对象转换为正则字符串
    if(v instanceof RegExp){
      return v.toString();
    }

    return v;
  });
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值