JSON.parse() 中 reviver参数的理解

本文探讨了JSON.parse()中reviver参数的作用,通过一个例子解释了如何使用reviver来转换解析后的值。当reviver函数返回undefined时,相应属性会被删除。根据MDN的描述,reviver函数的执行顺序类似于事件的捕获和冒泡阶段,从最内层属性向外层遍历。对于给定的JSON字符串,文章详细描述了这一过程,展示了如何逐层处理属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在去了解 JSON.parse() 中 reviver参数时发现了中有一个例子很有意思。
例子如下:

JSON.parse('{"p": 5}', (key, value) =>
  typeof value === 'number'
    ? value * 2 // 为数字时返回值*2
    : value     // 其他不变
);

// { p: 10 }

JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', (key, value) => {
  console.log(key); // 记录当前属性名,最后一个为""
  return value;     // 返回未改变的属性值
});

// 1
// 2
// 4
// 6
// 5
// 3
// ""

看看 MDN 对 reviver 参数的定义:

如果 reviver 指定了a ,则解析计算的值会 在返回之前进行转换。具体来说,计算出的值及其所有属性(从嵌套最多的属性开始并继续到原始值本身)分别通过 reviver . 然后它被调用,包含被处理的属性的对象 this ,属性名称作为字符串,属性值作为参数。如果 reviver 函数返回 undefined (或不返回任何值,例如,如果执行在函数结束后中断),则该属性将从对象中删除。否则,该属性将被重新定义为返回值。

如果 reviver only 转换某些值而不转换其他值,请确保按原样返回所有未转换的值,否则,它们将从结果对象中删除。

第一个例子很好理解:

JSON.parse('{"p": 5}', (key, value) =>
  typeof value === 'number'
    ? value * 2 // 为数字时返回值*2
    : value     // 其他不变
);

// { p: 10 }

去判断 JOSN.parse 中第一个参数是否为数字,如果是数字的话返回值要 *2 ,否则不变。

因此 p 的值改变,输出结果为10

但是到第二个例子时,前边还好理解,后边突然就感觉不太好,一起看看:

JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', (key, value) => {
  console.log(key); // 记录当前属性名,最后一个为""
  return value;     // 返回未改变的属性值
});

// 1
// 2
// 4
// 6
// 5
// 3
// ""

MDN 上说 reviver 属性是从嵌套最多的属性开始并继续到原始值本身。

个人理解相当于先进行 捕获事件 再进行 冒泡事件 ,一层一层,层层嵌套。

在当前 JSON.parse 传入的 text 为 string 类型的一长串:'{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}'

第一层为 {"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}} 拥有的东西如下:

  • "1": 1
  • "2": 2
  • "3": {"4": 4, "5": {"6": 6}}} 

第二层 {"4": 4, "5": {"6": 6}} 拥有的东西如下:

  • "4": 4
  • "5": {"6": 6}

 第三层 {"6": 6} 拥有的东西如下:

  • "6": 6

 因此先按照捕获事件来输出:

第一层输出:

1

2

 第二层输出:

4

第三层输出:

"捕获事件" 完成后,进行 "冒泡事件":

第三层 ==> 第二层 输出:

5

第二层 ==> 第一层 输出:

3

第一层 ==> 最底层 输出:

" "

因为整个输入 text 为 string 类型,所以最底层输出的为 " " 。

以上是我个人的理解,如有不对的地方还请大佬斧正。

参考资料:

JSON.parse() - JavaScript | MDNThe JSON.parse() method parses a JSON string, constructing the JavaScript value or object described by the string. An optional reviver function can be provided to perform a transformation on the resulting object before it is returned.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

### 使用 `JSON.parse` 方法及其参数详解 #### 解析 JSON 字符串并构建 JavaScript 对象 `JSON.parse()` 方法用于解析 JSON 字符串,构造由该字符串描述的 JavaScript 值或对象。此方法可以接受两个参数: - **text**: 必需。表示要解析成 JavaScript 对象的 JSON 文本。 - **reviver**: 可选。一个转换函数,在返回之前对所得到的对象执行变换操作。 ```javascript const jsonString = '{"name": "Alice", "age": 25}'; try { const parsedObject = JSON.parse(jsonString); console.log(parsedObject.name); // 输出 Alice } catch (error) { console.error("Invalid JSON string:", error.message); } ``` 当传入有效的 JSON 字符串时,上述代码成功创建了一个新的 JavaScript 对象,并访问其属性[^2]。 #### 处理嵌套结构中的特定字段 通过传递第二个参数——即 reviver 函数给 `JSON.parse()` ,可以在反序列化过程中修改数据。Reviver 函数接收键名和对应的值作为输入,并允许开发者自定义处理逻辑来调整最终的结果。 ```javascript function customReviver(key, value) { if (typeof value === 'string') { return `${value.toUpperCase()}!`; } return value; } const complexJsonString = '{"greeting": "hello world", "data": {"number": 42}}'; const modifiedObj = JSON.parse(complexJsonString, customReviver); console.log(modifiedObj.greeting); // HELLO WORLD! console.log(modifiedObj.data.number); // 42 ``` 在这个例子中,所有的字符串都被转换成了大写字母加上感叹号的形式,而其他类型的值保持不变。 需要注意的是,如果尝试直接解析非字符串形式的数据(如已经是一个对象),则会导致错误发生;同样地,对于不合法的 JSON 格式的字符串也会抛出异常。因此建议总是使用 try-catch 结构来进行安全的操作[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值