JSON.parse reviver函数嵌套对象

JSON.parse reviver function nested objects

我的目标是用可选的 reviver argument 告诉 JSON.parse 函数,如果传递给 calc(string) 函数的字符串有一个名为 [=15 的键,我会喜欢它=] 执行该表达式内部的操作,然后继续向外工作以对字符串的其余部分进行操作。

每次我 运行 我得到 NaN

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

因此,如果键是 "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);

几点:

  • 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);