如何解析包含函数的JSON字符串?

时间:2015-01-25 19:47:30

标签: javascript jquery json

我有一个JSON对象,如下所示:

string str = '[
  {
    "name": "data-input1",
    "type": "Element [in]",
    "description": "data-input1",
    "getConnectorPosition": "function (element) { return {x: 0, y: Math.floor(element.rectangle.width / 2)} }"
  },
  {
    "name": "data-output1",
    "type": "Element [out] [array]",
    "description": "data-output1",
    "getConnectorPosition": "function (element) { return {x: Math.floor(element.rectangle.width), y: Math.floor(element.rectangle.height / 2)} }"
  }
  ]';

我希望将此字符串解析为对象。

我收到此错误:

Uncaught TypeError: string is not a function

调用方法getConnectorPosition时。

阅读以前的问题我已经理解JSON中的函数并不完全是#34; legal",错误也暗示了这一点。

我究竟能如何正确地解析包含函数的JSON对象(如上所述),然后调用这些函数?

3 个答案:

答案 0 :(得分:2)

您的错误被抛出,因为在JavaScript中您没有将变量声明为特定类型,因此始终使用var关键字。如果您将string str更改为var str,那么您当前的错误将会消失。

然后,您需要确保您的字符串是单行的,或者您要转义文字换行符,因为JavaScript无法处理多行字符串:

     var str = '[\
        { "name": "data-input1", \
         "type": "Element [in]", \

无论如何,假设您正确声明str,并单行或转义换行符,您可以正常解析它:

var obj = JSON.parse(str);

并以字符串形式访问您的函数 ,如下所示:

obj[0].getConnectorPosition;

要实际使用您的功能,您必须对它们进行评估:

eval(obj[0].getConnectorPosition)

相同
function (element) { return { x: 0, y: Math.floor(element.rectangle.width / 2) } }

答案 1 :(得分:1)

您得到的实际错误是因为您应该写var str = ...而不是string

您可以获取包含该函数的子字符串,并使用eval将它们评估为函数。然而,这可能导致严重的安全和其他问题。引用Douglas Crockford:

  

eval函数(及其亲属,Function,setTimeout和setInterval)提供对JavaScript编译器的访问。这有时是必要的,但在大多数情况下,它表明存在极其糟糕的编码。 eval函数是JavaScript中最被滥用的特性。

如果你真的想走这条路,你可以使用eval来做,但你已被警告:)

顺便说一句,如果你已经解析了你的JSON,你可以这样做:

obj[0].getConnectorPosition = eval(obj[0].getConnectorPosition);

所以你用评估的方法替换前一个字符串。

答案 2 :(得分:1)

这是一个将包含函数的json字符串转换回具有有效函数声明的json对象的示例。

var jsonstring = "{\"schema\": {\"title\": \"User Feedback\",        \"description\":\"so\", \"type\":\"object\", \"properties\":{\"name\":{\"type\":\"string\"}}}," + "\"options\":{ \"form\":{\"attributes\":{}, \"buttons\":{ \"submit\":{ \"title\":\"It\", \"click\":\"function(){alert('hello');}\" }}} }}";

var jsonData = JSON.parse(jsonstring);

function Iterate(data)
{
      jQuery.each(data, function (index, value) {
        if (typeof value == 'object') {
            Iterate(value);
        }
        else {
            if (value.indexOf("function()") > -1)
                data[index] = eval("(" + value + ")");
        }
    });

};

Iterate(jsonData);
//call the embedded function 
jsonData.options.form.buttons.submit.click();