devalue高级技巧如何优雅处理正则表达式、日期和符号键【免费下载链接】devalueGets the job done when JSON.stringify cant项目地址: https://gitcode.com/gh_mirrors/de/devaluedevalue 是一个比JSON.stringify更强的 JavaScript 序列化库它能优雅地处理正则表达式、日期、循环引用、Map/Set 等原生类型是 Svelte 官方生态的序列化利器。本文将从新手视角带你掌握 devalue 序列化正则表达式、日期Date和符号键Symbol keys的 3 个实用技巧并学会用自定义类型扩展它的能力。 devalue 是什么为什么 JSON.stringify 不够用JSON.stringify是前端最常用的序列化方法但它有几个硬伤数据类型JSON.stringify 的表现devalue 的表现正则表达式变成{}✅ 完整保留源码和标志位日期转成字符串信息丢失✅ 精确还原为 Date 对象循环引用直接抛错✅ 自动去重Map / Set变成{}✅ 完整还原NaN / Infinity / -0变成null✅ 精确保留devalue 提供两种使用模式uneval 模式把值转成一段可直接eval的 JavaScript 代码输出最紧凑stringify / parse 模式类似JSON.stringifyJSON.parse输出标准 JSON跨传输更安全入门示例可参考 README.md 中的 Usage 部分。 快速安装两种方式任选方式一npm 安装推荐npm install devalue方式二克隆源码研究git clone https://gitcode.com/gh_mirrors/de/devalue核心实现分布在 src/stringify.js序列化、src/parse.js反序列化、src/uneval.js代码生成三个文件类型定义见 src/types.d.ts逻辑清晰非常适合阅读。 技巧一正则表达式的保真序列化用JSON.stringify序列化正则表达式会得到一个空对象{}信息全丢。而 devalue 会同时保存正则的source源码和flags标志位反序列化后与原始正则完全等价。import * as devalue from devalue; const re /abc/gim; // stringify 模式JSON 中存为 [RegExp, abc, gim] const json devalue.stringify(re); const restored devalue.parse(json); // /abc/gim从 src/stringify.js 可以看到devalue 通过regExpInfo操作提取正则的source和flags再打包成带RegExp标签的数组反序列化时由 src/parse.js 中的fromRegExpInfo操作重建。两个实用点重复引用自动去重同一正则出现多次时只序列化一次见 test/index.test.js 中的重复引用测试XSS 安全正则源码中的等危险字符会被转义为\u003C嵌入script标签也不会被攻击者利用这对服务端渲染注入初始状态数据非常关键 技巧二日期序列化的正确姿势JSON.stringify(new Date())会丢失类型恢复时还得手动new Date(str)。devalue 直接保存 ISO 8601 时间字符串反序列化后仍是真正的Date实例const date new Date(1e12); const json devalue.stringify(date); // 输出[[Date,2001-09-09T01:46:40.000Z]] const restored devalue.parse(json); console.log(restored instanceof Date); // true新手最容易踩的坑——无效日期new Date()这种 Invalid Date 不会被跳过devalue 会序列化为[[Date,]]恢复时还原为同样无效的 Date 对象对应new Date(NaN)。相关处理逻辑在 src/operations.js 的toISOString操作中测试用例见 test/index.test.js。建议如果业务上不应出现无效日期可以在序列化前先校验isNaN(date.getTime())提前拦截脏数据。 技巧三优雅应对符号键Symbol keys这是 devalue 中最有态度的设计带可枚举符号键的普通对象序列化时会直接报错错误信息为Cannot stringify POJOs with symbolic keys直接序列化 Symbol 原始值则报Cannot stringify a Symbol primitive。const obj { [Symbol(id)]: 1 }; devalue.stringify(obj); // 抛出 DevalueError且 e.path 会精确指出符号键的位置为什么故意报错因为 JSON 格式本身无法表达符号键而 devalue 坚持要么正确还原要么明确失败绝不悄悄丢数据。判断逻辑见 src/stringify.js 的shape.kind symbol-keys分支。优雅的处理思路有三种用错误定位问题捕获错误后读取e.path属性它能精确定位到出错符号键的完整路径如.object.array[0]错误类定义在 src/utils.js序列化前转换数据把符号键映射为字符串键例如{ id: 1 }这是最通用的做法封装为自定义类型如果整个对象是一个含符号键的领域对象用下面的自定义类型机制整体接管 进阶用自定义类型reducer/reviver扩展 devaluedevalue 允许你注册自定义类型序列化时用 reducer 把对象转成普通数据反序列化时用 reviver 还原class Config { #id Symbol(id); // 符号键藏在私有字段里 constructor(name) { this.name name; } } const json devalue.stringify(new Config(demo), { Config: (v) v instanceof Config { name: v.name } // reducer }); const cfg devalue.parse(json, { Config: ({ name }) new Config(name) // reviver });只要 reducer 返回真值devalue 就会认为这个值我认识按[Config, ...]格式序列化。这套机制让符号键对象、类实例等JSON 表示不了的数据都能安全过网完整示例见 README.md 的 Custom types 章节。✅ 小结devalue 高级技巧速查清单场景技巧正则表达式直接序列化source 与 flags 完整保留且自动 XSS 转义日期ISO 8601 存储还原为真正的 Date先拦截 Invalid Date符号键序列化前转字符串键或用自定义类型整体接管报错排查捕获DevalueError读取e.path定位问题字段类实例注册 reducer reviver 自定义类型最后提醒devalue 生成的 JSON 必须用devalue.parse或unflatten解析不要用JSON.parse直接解析反之uneval的输出适合从服务端安全注入到客户端但不建议把客户端传来的uneval结果直接eval。掌握这些技巧你的序列化方案会比JSON.stringify健壮得多 【免费下载链接】devalueGets the job done when JSON.stringify cant项目地址: https://gitcode.com/gh_mirrors/de/devalue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考