美文网首页让前端飞
函数在JSON中如何保存?

函数在JSON中如何保存?

作者: 小飞牛牛 | 来源:发表于2022-01-26 11:52 被阅读0次

    熟悉前端的童鞋都知道,JSON格式是无法保存函数格式的。
    然而,JSON提供了stringify和parse的一些特殊机制,可以实现这一需求。

    思路:在将对象转换成字符串时,将函数参数和函数体分别保存成字符串。在获取json转换回对象时,将其还原为方法。

    首先,我们需要准备两个方法,用来获取函数的参数和函数体。

    // 获得函数参数
     function getFunctionArgsName(func) {
            var args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]
            return args
              .split(',')
              .map(function (arg) {
                return arg.replace(/\/\*.*\*\//, '').trim()
              })
              .filter(function (_args) {
                //确保没有undefineds
                return _args
              })
          }
    // 获得函数体
    function getFunctionBody(func) {
        var args = func.toString().match(/(function\s.*?\(([^)]*)\))/)[1]
        var funBody = func.toString().replace(args, '')
        funBody = funBody.replace(/^[\s]*\{/, '')
        funBody = funBody.replace(/\}[\s]*$/, '')
        return funBody
      }
    

    假设有这样的对象

    var func = function(a, b) {
        return a + b;
    }
    var foo = {
        name: 'mike',
        func: func
    }
    console.log(JSON.stringify(foo))
    

    当使用JSON.stringify转换后,func函数会丢失。然而,JSON.stringify还有一个特性,当对象中包含有toJSON方法时,会调用该方法进行序列化。如此,我们就可以在函数赋值给对象前给函数增加一个方法。

    var func = function(a, b) {
        return a + b;
    }
    func.toJSON = function() {
     return JSON.stringify({
          args: getFunctionArgsName(func),
          body: getFunctionBody(func)
        })
    }
    var foo = {
        name: 'mike',
        func: func
    }
    console.log(JSON.stringify(foo))
    

    打印结果

    {"name":"mike","func":"{\"args\":[\"a\",\"b\"],\"body\":\"\\n        return a + b\\n      \"}"}
    

    在用JSON.parse 转换对象时,会获得一个对函数的描述对象,可通过JSON.parse的第二个参数(过滤函数), 对其进行特殊处理

    var jsonString = JSON.stringify(foo);
     var parseObj = JSON.parse(jsonString, function (key, value) {
        if (key === 'func') {
          const fnobj = JSON.parse(value)
          return new Function(...fnobj.args, fnobj.body)
        } else {
          return value
        }
    })
    console.log(parseObj.func(1,2))
    

    完整代码如下:

     <body>
        <script>
          function getFunctionArgsName(func) {
            var args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1]
            return args
              .split(',')
              .map(function (arg) {
                return arg.replace(/\/\*.*\*\//, '').trim()
              })
              .filter(function (_args) {
                //确保没有undefineds
                return _args
              })
          }
          function getFunctionBody(func) {
            var args = func.toString().match(/(function\s.*?\(([^)]*)\))/)[1]
            var funBody = func.toString().replace(args, '')
            funBody = funBody.replace(/^[\s]*\{/, '')
            funBody = funBody.replace(/\}[\s]*$/, '')
            return funBody
          }
          var func = function (a, b) {
            return a + b
          }
          func.toJSON = function () {
            return JSON.stringify({
              args: getFunctionArgsName(func),
              body: getFunctionBody(func)
            })
          }
          var foo = {
            name: 'mike',
            func: func
          }
          console.log(JSON.stringify(foo))
          var jsonString = JSON.stringify(foo)
          var parseObj = JSON.parse(jsonString, function (key, value) {
            if (key === 'func') {
              const fnobj = JSON.parse(value)
              return new Function(...fnobj.args, fnobj.body)
            } else {
              return value
            }
          })
          console.log(parseObj.func(1, 2))
        </script>
      </body>
    

    打印结果

    {"name":"mike","func":"{\"args\":[\"a\",\"b\"],\"body\":\"\\n        return a + b\\n      \"}"}
    3
    

    相关文章

      网友评论

        本文标题:函数在JSON中如何保存?

        本文链接:https://www.haomeiwen.com/subject/vhiwhrtx.html