Javascript JSON.parse reviver函数嵌套对象

Javascript JSON.parse reviver函数嵌套对象,javascript,json,parsing,reviver-function,Javascript,Json,Parsing,Reviver Function,我的目标是使用可选的reviver参数告诉JSON.parse函数,如果传递给calc(string)函数的字符串有一个名为“expr”的键来执行该表达式内部的操作,我会使用它,然后继续向外工作,对管柱的其余部分进行操作 每次运行此命令时,我都会得到NaN 如果我在console.log(initNumber)之前注释掉最后两个calc(string)调用,那么程序将按预期运行 因此,如果键是“expr”,嵌套的“op”键的值是“add”,则对该嵌套对象执行add()函数。如果“op”键是“su

我的目标是使用可选的
reviver参数告诉
JSON.parse
函数,如果传递给
calc(string)
函数的字符串有一个名为
“expr”
的键来执行该表达式内部的操作,我会使用它,然后继续向外工作,对管柱的其余部分进行操作

每次运行此命令时,我都会得到
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
    转换为一个值,那么您的
    add
    subtract
    函数需要能够读取这些值,而不仅仅是
    number
    ——我想,您可能想要不同的逻辑。这就是为什么我用下面的方法得到操作数。无论哪种方式,您都需要知道可能没有
    number
    参数,并处理它
  • 您获取
    NaN
    的原因是由于上述原因-您试图从没有编号的对象(恢复
    expr
    s的结果)获取
    编号
    ,这会导致
    未定义
    ,从而破坏计算
基本上,记住这一点

{“op”:“subtract”,“expr”:{“op”:“add”,“number”:15}}

{“op”:“subtract”,“expr”:37}

在恢复表达式之后,需要处理它

var initNum=0;
var calc=函数(字符串){
var calcObj=JSON.parse(字符串,reviver);
添加(calcObj);
减去(calcObj);
};
var add=功能(obj){
如果(obj[“op”]=“添加”){
变量操作数=(obj[“number”])?obj[“number”]:obj[“expr”];
initNum=操作数+initNum;
log(“运行总数:+initNum”);
返回initNum;
}
}
var减法=函数(obj){
if(obj[“op”]=“减法”){
变量操作数=(obj[“number”])?obj[“number”]:obj[“expr”];
initNum=initNum-操作数;
log(“运行总数:+initNum”);
返回initNum;
}
}
var恢复器=功能(键,val){
如果(键==“expr”){
如果(val.op==“添加”){
返回添加(val);
}
否则如果(val.op==“减法”){
返回减法(val);
}
}
否则{
返回val;
}
};
计算(“{”op:“添加”,“编号”:5}”);
计算(“{”op:“减法”,“数字”:2}”);
计算(“{”op:“添加”,“编号:19}”);
计算(“{”op:“减法”,“表达式”:{”op:“加”,“数”:15}”);
计算(“{”op:“add”,“expr:{”op:“add”,“expr:{”op:“subtract”,“number”:3}}}”);

console.log(initNum)如果JSON对象有一个“number”键,请使用该键,否则请使用“expr”键
是的,完全正确。而且由于
revivier
是“从最嵌套的属性开始,然后继续到原始值本身”,所以所有
expr
s在被周围的
add
subtract
操作看到时,应该已经转换为它们的值。真是太棒了。完全有道理。:)