【JS】JSON把我的function搞丢了怎么办?深入理解与灵活运用 JSON 序列化与反序列化

引言

在日常开发中,我们经常遇到需要将 JavaScript 对象转化为 JSON 字符串进行传输或者持久化存储的情况,这时 JSON.stringify()JSON.parse() 成为了我们的得力助手。然而,原生的 JSON 序列化并不能处理函数、日期、正则等非基础类型数据,这无疑给我们的工作带来了一定挑战。本文将探讨如何自定义序列化与反序列化方法以保留这些信息,并顺带提及在特定场景下,简单地使用解构赋值也能满足对象拷贝的需求。

函数类型的序列化与反序列化

原生 JSON 序列化会忽略对象中的函数成员。若要保留函数,我们可以创建自定义的序列化和反序列化函数。以下是一个简单的实现示例:

function customSerialize(obj) {
  let copy = {...obj}; // 创建浅拷贝
  if (typeof obj === 'function') {
    copy._fnBody = obj.toString();
  }
  return copy;
}

function customDeserialize(jsonObj) {
  if ('_fnBody' in jsonObj) {
    jsonObj._fn = new Function(jsonObj._fnBody);
    delete jsonObj._fnBody;
  }
  return jsonObj;
}

在这个例子中,我们将函数体转为字符串存储,并在反序列化时利用 new Function() 来重建函数。不过需要注意的是,动态创建函数存在一定的安全隐患,尤其在严格的安全策略环境中可能无法使用。

Date 和 RegExp 类型的序列化与反序列化

对于 Date 和 RegExp 类型,同样可以通过定制化的方法来进行序列化与反序列化:

function customSerialize(obj) {
  let copy = {...obj};
  if (obj instanceof Date) {
    copy._date = obj.toISOString();
  } else if (obj instanceof RegExp) {
    copy._regex = [obj.source, obj.flags];
  }
  return copy;
}

function customDeserialize(jsonObj) {
  if ('_date' in jsonObj) {
    jsonObj._date = new Date(jsonObj._date);
  } else if ('_regex' in jsonObj) {
    jsonObj._regex = new RegExp(jsonObj._regex[0], jsonObj._regex[1]);
  }
  return jsonObj;
}

这里我们分别利用 toISOString() 方法将 Date 对象转为 ISO 格式字符串,将正则表达式的 sourceflags 存储下来以便重构。

对象拷贝场景下的解构赋值

当我们的目标仅仅是复制对象而不涉及 JSON 序列化时,可以巧妙地使用 ES6 中的解构赋值语法实现深拷贝:

let originalObj = { a: 1, b: function() { console.log('hello'); }, c: new Date() };
let copiedObj = {...originalObj};

// 对于函数和 Date 类型,它们也会被正确复制
copiedObj.b(); // 输出 "hello"
console.log(copiedObj.c instanceof Date); // true

需要注意的是,解构赋值只能实现一层深度的浅拷贝,对于嵌套对象,需要递归或者其他深拷贝方法才能完整复制所有层级。

总结起来,虽然原生 JSON 序列化不支持函数、日期、正则等类型,但通过自定义序列化与反序列化方法,我们可以扩展这一能力。而在单纯的对象拷贝场景中,利用解构赋值不失为一种简洁高效的选择。在实际开发中,应根据具体需求选择最合适的方案。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值