2017-10-22 114 views
1

我的目标是告诉功能与可选reviver argument,我希望它是否传递给calc(string)函数的字符串有一个名为"expr"的键执行该表达式内的操作,然后继续向外工作以操作其余的字符串。JSON.parse reviver函数嵌套对象

每当我运行这个我越来越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); 

回答

1

的几点:

  • reviver会给你已经被解析的值,则不需要再次解析他们。
  • 如果您将expr转换为值,您的addsubtract函数需要能够读取这些值,而不仅仅是number - 我想,也许您打算使用不同的逻辑。这就是为什么我按照我的方式得到operand。无论哪种方式,您都需要意识到可能没有number参数,并处理该参数。
  • 你得到的原因是NaN正是因为上述原因 - 你试图从没有物体的number中得到 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);

+0

谢谢你这么多。这使得wayyyyyyy现在更有意义。因此,在var操作数部分中,您现在说“如果JSON对象具有”数字“键,请使用该键,否则使用”expr“键。”谢谢谢谢。 – giggidy

+0

'如果JSON对象有一个“数字”键,那么使用它,否则使用“expr”键'是的,确切地说。并且因为'reviver'是[定义](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Using_the_reviver_parameter)“工作”,从最嵌套的属性开始进行到原来的价值本身',所有'expr's应该已经被转换为他们的价值观,当他们被看到'add或'subtract'围绕他们。 –

+0

刚刚辉煌。总体感觉。 :) – giggidy