JSON.parse reviver函数嵌套对象

时间:2017-10-22 00:38:45

标签: javascript json parsing reviver-function

如果传递给JSON.parse函数的字符串有一个名为reviver argument的键,我的目标是告诉calc(string)函数使用我想要的"expr"。执行该表达式内部的操作,然后继续向外工作以对字符串的其余部分进行操作。

每次我运行时,我都会NaN

如果我在calc(string)之前注释掉最后两个console.log(initNumber)来电,那么该程序会按预期运行。

因此,如果密钥为"expr"且嵌套"op"密钥的值为"add",则对该嵌套对象执行add()函数。如果"op"密钥为"subtract",则同样如此。

非常感谢任何帮助。

var initNum = 0;

var calc = function(string) {
    var calcString = JSON.parse(string, reviver);

    add(calcString);
    subtract(calcString);
};

var add = function(string) {
    if (string["op"] == "add") {
    var numString = parseInt(JSON.stringify(string["number"]));
    initNum = numString + initNum;
    return initNum;
  }
}
var subtract = function(string) {
    if (string["op"] == "subtract") {
    var numString = parseInt(JSON.stringify(string["number"]));
    initNum = initNum - numString;
    return initNum;
  }
}

var reviver = function(key, val) {
  if (key == "expr") {
    if (val.op == "add") {
      return add(val);
    }
    else if (val.op == "subtract") {
      return subtract(val);
    }
  }
    else {
      return val;
    }
};

calc('{"op" : "add", "number" : 5}');
calc('{"op" : "subtract", "number" : 2}');
calc('{"op" : "add", "number" : 19}');
calc('{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}');
calc('{"op": "add", "expr" : {"op" : "add", "expr" : {"op" : "subtract", "number" : 3}}}');
console.log(initNum);

1 个答案:

答案 0 :(得分:1)

几点:

  • reviver将为您提供已解析的值,您无需再次解析它们。
  • 如果您将expr转换为值,则addsubtract函数需要能够读取这些值,而不仅仅是number - 我认为,也许你打算采用不同的逻辑。这就是为什么我按照下面的方式获得operand。无论哪种方式,您都需要注意可能没有number参数,并处理它。
  • 你得到NaN的原因是由于上述原因 - 你试图从没有一个的对象中获取number(恢复expr s的结果) ,这会让你undefined打破计算。

基本上,请记住

{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}

转到

{"op": "subtract", "expr" : 37}

恢复表达式后

,所以你需要处理它。

var initNum = 0;

var calc = function(string) {
    var calcObj = JSON.parse(string, reviver);

    add(calcObj);
    subtract(calcObj);
};

var add = function(obj) {
    if (obj["op"] == "add") {
      var operand = (obj["number"])? obj["number"] : obj["expr"];
      initNum = operand + initNum;
      console.log("running total : "+initNum);
      return initNum;
  }
}
var subtract = function(obj) {
    if (obj["op"] == "subtract") {
      var operand = (obj["number"])? obj["number"] : obj["expr"];
      initNum = initNum - operand;
      console.log("running total : "+initNum);
      return initNum;
  }
}

var reviver = function(key, val) {
  if (key == "expr") {
    if (val.op == "add") {
      return add(val);
    }
    else if (val.op == "subtract") {
      return subtract(val);
    }
  }
    else {
      return val;
    }
};

calc('{"op" : "add", "number" : 5}');
calc('{"op" : "subtract", "number" : 2}');
calc('{"op" : "add", "number" : 19}');
calc('{"op": "subtract", "expr" : {"op" : "add", "number" : 15}}');
calc('{"op": "add", "expr" : {"op" : "add", "expr" : {"op" : "subtract", "number" : 3}}}');
console.log(initNum);