如何将字符串日期转为Moment对象?含Moment对象的数组深拷贝方案
解决Moment对象深拷贝后转字符串的问题
你遇到的问题很典型——JSON.parse(JSON.stringify())虽然是常用的深拷贝手段,但它会把Moment这类特殊对象序列化为ISO字符串,丢失原有的Moment实例属性,导致日期选择器无法识别。下面分两种思路解决:
一、把序列化后的字符串转回Moment对象
如果已经用JSON方法完成了拷贝,只需要遍历数组,将每个startRealTime字段重新包装成Moment对象即可:
// 假设拷贝后的数组是copiedArray const fixedArray = copiedArray.map(item => ({ ...item, startRealTime: moment(item.startRealTime) }));
Moment构造函数可以直接接收ISO格式的字符串,返回一个新的Moment实例,这样就能让日期选择器正常识别了。
二、无需JSON序列化的深拷贝方法
更彻底的做法是用能保留Moment对象的深拷贝方式,避免序列化的问题:
1. 针对简单结构的手动拷贝
如果你的数组元素结构不复杂,直接用map配合对象展开运算符就能实现深拷贝,同时保留Moment实例:
const originalArray = [{startRealTime: moment("2018-05-17T05:55:01.149Z"), startTime:685}]; const deepCopied = originalArray.map(item => ({ ...item, startRealTime: moment(item.startRealTime) // 复制Moment对象 }));
这里moment(item.startRealTime)会创建一个新的Moment实例,避免和原对象引用同一内存。
2. 递归深拷贝(通用复杂结构)
如果数组里的嵌套层级多,可以写一个递归函数,专门处理Moment对象:
function deepCopyWithMoment(obj) { if (moment.isMoment(obj)) { return moment(obj); } if (typeof obj !== 'object' || obj === null) { return obj; } if (Array.isArray(obj)) { return obj.map(item => deepCopyWithMoment(item)); } const copiedObj = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { copiedObj[key] = deepCopyWithMoment(obj[key]); } } return copiedObj; } // 使用示例 const deepCopiedArray = deepCopyWithMoment(originalArray);
这个函数会递归遍历每个值,遇到Moment对象就复制一个新实例,其他类型正常拷贝。
3. 使用Lodash的自定义深拷贝
如果你项目里已经引入了Lodash,可以用_.cloneDeepWith方法,自定义Moment对象的复制逻辑:
const deepCopiedArray = _.cloneDeepWith(originalArray, (value) => { if (moment.isMoment(value)) { return moment(value); } });
Lodash的这个方法会自动处理大部分深拷贝场景,你只需要指定特殊类型(比如Moment)的复制规则即可。
内容的提问来源于stack exchange,提问作者Amit Chauhan
相关产品推荐
相关产品推荐

