You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JSON.stringify replacer函数异常:保留指定前缀属性失效问题

问题:为何用JSON.stringify的replacer保留特定前缀属性失败,移除却正常?

我想保留对象中所有属性名以特定字符串开头的属性,移除其他属性。但以下尝试仅保留foo属性的代码返回undefined,相反逻辑(移除foo)却能正常运行。

代码示例:

const o = {
  foo: 1,
  bar: 2,
  baz: 3
};
console.log(JSON.stringify(o, (k, v) => k.startsWith('f') ? v : undefined)); // undefined -> 为什么不是 {"foo":1} ?
console.log(JSON.stringify(o, (k, v) => !k.startsWith('f') ? undefined : v)); // undefined -> 为什么不是 {"foo":1} ?
console.log(JSON.stringify(o, (k, v) => !k.startsWith('f') ? v : undefined)); // {"bar":2,"baz":3}

Object.keys(o).forEach(key => {
  console.log(key, key.startsWith('f'));
});
// foo,true
// bar,false
// baz,false

原因分析

问题出在JSON.stringify的replacer函数的初始调用规则上:

  • 第一次调用replacer时,参数k是空字符串"",对应的v是整个目标对象o。
  • 当你写k.startsWith('f') ? v : undefined时,空字符串不满足前缀条件,直接返回undefined,这会让JSON.stringify直接丢弃整个对象,最终输出undefined。
  • 而相反逻辑!k.startsWith('f') ? v : undefined时,空字符串满足条件,返回整个对象,之后replacer才会遍历对象的每个属性,此时排除foo、保留其他属性,所以能正常输出结果。

解决方法

方法1:处理replacer的初始调用

在replacer里先判断初始调用的空字符串情况,返回整个对象后再过滤属性:

console.log(JSON.stringify(o, (k, v) => {
  if (k === "") return v; // 处理初始调用,返回整个对象
  return k.startsWith('f') ? v : undefined; // 过滤属性
})); // 输出 {"foo":1}

方法2:提前过滤对象再序列化

直接先把对象过滤好,再进行JSON序列化,逻辑更直观:

const filteredObj = Object.fromEntries(
  Object.entries(o).filter(([key]) => key.startsWith('f'))
);
console.log(JSON.stringify(filteredObj)); // 输出 {"foo":1}

内容的提问来源于stack exchange,提问作者droptix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:11:18