0

JSBin 链接让你可以快速运行代码。

JSbinhere

问题出在评论中,但是从文档中关于复活者(这个名字很糟糕)的工作方式来看,如果你不返回值或者如果你返回undefined,那么应该从对象中删除该属性。如果您返回未转换的值,它保持不变。

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

但在第二个例子中,我什至没有得到一个对象,只是未定义。那么我是误读了文档还是有其他问题?

在第二个示例中,结果只是未定义。

    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
4

1 回答 1

1

Your second example left return value; off.

But even tough you did that, it should only have removed the properties that returned undefined as value, and I think you found a bug (may be?).

From one of MDN JSON.parse examples it says that last key is "" when JSON.parse is called

I managed to reproduce your code with the undefined error and it seems that if you return the value for the "" key, like

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

it appears to work as expected.

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 }

EDIT:

So, reading ECAMScript JSON.parse(text [, reviver]) specification, it seems that this is the expected behavior. When it describes the behavior f calling the reviver function, the last step after calling all DefineOwnProperty items is

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

So, when you don't return a value for the '' name at your reviver function, it understand that it should remove that, which stands for the whole object to be returned, resulting in it being undefined for the JSON.parse return.

That explains the concern on MDN docs when it says

be certain to return all untransformed values as-is

But I agree that it should be more explicit about how these small nuances work.

于 2016-10-23T20:59:54.273 回答