javascript - JSON.parse Reviver 函数中出现意外行为,删除对象而不是关键属性

标签 javascript json reviver-function

JSBin 链接,以便您可以快速运行代码。

JSbinhere

问题出在注释中,但是根据文档说明,如果您不返回值或返回undefined,那么reviver(这个名字很糟糕)是如何工作的属性应该从对象中删除。如果您返回未转换的值,它将保持不变。

然而,当我测试它时,看起来整个对象都被删除了。第一个示例工作得很好,偶数转换为负数,奇数不变。

但在第二个示例中,我什至没有返回对象,只是未定义。那么我是误读了文档还是其他错误?

第二个示例中的结果未定义。

    var obj = {
            one: 1,
            innerObj: {
                two: 2,
                four: 4
            },
            two: 2,
            three: 3,
            four: 4
        },
            b = {},
            json = JSON.stringify(obj);
        /**
         *  This works as expected.
         */
        b = JSON.parse(json, function (name, value) {
            if (value % 2 === 0) {
                return -value;
            }
            return value;
        });
        console.log(b);
    /**
    [object Object] {
   four: -4,
   innerObj: [object Object] {
    four: -4,
    two: -2
   },
   one: 1,
   three: 3,
   two: -2
    } 
    */

    obj = {
            one: 1,
            innerObj: {
                two: 2,
                four: 4
            },
            two: 2,
            three: 3,
            four: 4
        };
        b = {};
        json = JSON.stringify(obj);
        /**
         * This does not work as expected, instead of deleting the property on the object, the entire object returns undefined.
         */
        b = JSON.parse(json, function (name, value) {
            if (value % 2 === 0) {
                return -value;
            }

        });
        console.log(b);
// undefined

最佳答案

您的第二个示例将 return value; 关闭。

但即使你这样做了,它也应该只删除返回 undefined 作为值的属性,我认为你发现了一个错误(可能是?)。

来自 MDN JSON.parse examples 之一它说当调用 JSON.parse 时,最后一个键是 ""

我成功地重现了您的代码,但出现了 undefined 错误,并且似乎如果您返回 "" 键的值,例如

if (name == "") {
  return value;
}

它似乎按预期工作。

obj = {
   one: 1,
   innerObj: {
     two: 2,
     four: 4
   },
   two: 2,
   three: 3,
   four: 4
};
b = {};
json = JSON.stringify(obj);


/**
* This does not work as expected, instead of deleting the property on the object, the entire object returns undefined.
*/
b = JSON.parse(json, function (name, value) {
  if (value % 2 === 0) {
    return -value;
  }
  if (name == "") {
    return value;
  }
});
console.log(b);
// { two: -2, four: -4 }
<小时/>

编辑:

所以,阅读ECAMScript JSON.parse(text [, reviver]) specification ,这似乎是预期的行为。当它描述调用reviver函数的行为时,调用所有DefineOwnProperty项后的最后一步是

Return the result of calling the abstract operation Walk, passing root and the empty String.

因此,当您在 reviver 函数中没有返回 '' 名称的值时,它会理解它应该删除该值,它代表要返回的整个对象,从而导致JSON.parse 返回的未定义

这解释了 MDN 文档上所说的担忧

be certain to return all untransformed values as-is

但我同意应该更明确地说明这些细微差别如何发挥作用。

关于javascript - JSON.parse Reviver 函数中出现意外行为,删除对象而不是关键属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40207547/

相关文章:

javascript - 点击,触发动画和播放声音。从按键到点击

java - 使用gson解析大json文件

iphone - 如何在 json web 服务中传递参数和参数?

javascript - JSON.parse reviver 函数有 n+1 个键?

javascript - 如何使用 fetch.response.json() 的 reviver 函数

JavaScript。一旦我添加 math.floor 函数,calc() 函数就不起作用

javascript - 从函数参数创建 arraylist

javascript - Lambda 将 SQL 传递到 RDS 数据 API 时出错

javascript - 如何使用 JSON 类型索引从 JSON 变量获取数据