如何在 JSON 中存储 javascript 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36517173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:11:24  来源:igfitidea点击:

How to store a javascript function in JSON

javascriptjson

提问by Amit

I have a JS object I would like to save in Local Storage for future use, and I cannot parse it to a string.

我有一个 JS 对象,我想保存在本地存储中以备将来使用,但我无法将其解析为字符串。

Code:

代码:

JSON.stringify({
    a: 5,
    b: function (param) {
        return param;
    }
})

Result:

结果:

"{"a":5}"

How do I save it for future use, if not with JSON?

如果不使用 JSON,我该如何保存以备将来使用?

(And creating my own Lexer-Parser to interupt string function I dont think is an option)

(并创建我自己的 Lexer-Parser 来中断字符串函数,我认为这不是一个选项)

回答by T.J. Crowder

Usually a question like this indicates an X/Y problem: You need to do X, you think Y will help you do that, so you try to do Y, can't, and ask how to do Y. It would frequently be more useful to ask how to do X instead.

通常这样的问题表示一个 X/Y 问题:你需要做 X,你认为 Y 会帮助你做到这一点,所以你尝试做 Y,不能,并询问如何做 Y。它通常会更多询问如何做 X 很有用。

But answering the question asked: You coulduse replacer and reviver functions to convert the function to a string (during stringify) and back into a function (during parse) to store a string version of the function, but there are all sorts of issues with doing that, not least that the scope in which the function is defined may well matter to the function. (It doesn't matter to the function you've shown in the question, but I assume that's not really representative.) And converting a string from local storage into code you may run means that you are trusting that the local storage content hasn't been corrupted in a malicious way. Granted it's not likely unless the page is already vulnerable to XSS attacks, but it's an issue to keep in mind.

但是回答提出的问题:您可以使用 replacer 和 reviver 函数将函数转换为字符串 (during stringify) 并返回到函数 (during parse) 以存储函数的字符串版本,但是这样做有各种各样的问题,尤其是定义函数的范围可能对函数很重要。(这与您在问题中显示的函数无关,但我认为这不是真正具有代表性的。)并且将字符串从本地存储转换为您可以运行的代码意味着您相信本地存储内容没有t 被恶意破坏。当然,除非页面已经容易受到 XSS 攻击,否则不太可能,但这是一个需要记住的问题。

Here's an example, but I don't recommend it unless other options have been exhausted, not least because it uses eval, which (like its close cousin new Function)) can be a vector for malicious code:

这是一个例子,但我不推荐它,除非其他选项已经用尽,尤其是因为它使用eval,它(就像它的近亲new Function))可能是恶意代码的载体:

// The object
var obj = {
    a: 5,
    b: function (param) {
        return param;
    }
};

// Convert to JSON using a replacer function to output
// the string version of a function with /Function(
// in front and )/ at the end.
var json = JSON.stringify(obj, function(key, value) {
  if (typeof value === "function") {
    return "/Function(" + value.toString() + ")/";
  }
  return value;
});

// Convert to an object using a reviver function that
// recognizes the /Function(...)/ value and converts it
// into a function via -shudder- `eval`.
var obj2 = JSON.parse(json, function(key, value) {
  if (typeof value === "string" &&
      value.startsWith("/Function(") &&
      value.endsWith(")/")) {
    value = value.substring(10, value.length - 2);
    return (0, eval)("(" + value + ")");
  }
  return value;
});
document.body.innerHTML = obj2.b(42);

The construct (0, eval)("(" + value + ")");ensures that evalruns at global scope rather than within the scope of the reviver function. Normally evalhas a magic ability to use the scope you call it in, but that only works when you call it directly. Indirect evalas shown (or just var e = eval; e("(" + value + ")");) doesn't have that magic ability, it runs at global scope.

该构造(0, eval)("(" + value + ")");确保eval在全局范围内运行,而不是在 reviver 函数的范围内运行。通常eval具有使用您调用它的作用域的魔法能力,但只有在您直接调用它时才有效。如图所示的间接eval(或只是var e = eval; e("(" + value + ")");)没有这种神奇的能力,它在全局范围内运行。

回答by Kostiantyn

I'd recommend this approach:

我推荐这种方法:

Store arguments and the body in your json:

将参数和正文存储在您的 json 中:

{"function":{"arguments":"a,b,c","body":"return a*b+c;"}}

Now parse json and instantiate the function:

现在解析 json 并实例化函数:

var f = new Function(function.arguments, function.body);

I think it's save

我认为这是保存

回答by denysdovhan

You can't store functions in JSON.

您不能在 JSON 中存储函数。

The value in JSON may contain only string, number, object, array, true, falseor null:

在JSON的值可能只包含字符串号码对象阵列truefalsenull

enter image description here

在此处输入图片说明

Check out it on JSON site.

在 JSON 站点上查看它。

回答by Redu

One simple way of doing this is

一种简单的方法是

var dstr = JSON.stringify( { a: 5
                           , b: x => x
                           }
                         , (k,v) => typeof v === "function" ? "" + v : v
                         );

回答by ESR

I've taken to storing the function name, along with the parameter values, in an array, with the first item in the array being the function name prepended with a $, to separate them from normal arrays.

我已经将函数名和参数值一起存储在一个数组中,数组中的第一项是函数名,前面带有 a $,以将它们与普通数组分开。

{
    "object": {
        "your-function": ["$functionName", "param-1", "param-2"],
        "color": ["$getColor", "brand", "brand-2"],
        "normal-array": ["normal", "array"]
        ...
    }
}

In the above example I have Sass and JS functions to retrieve color values from a global map/object. Parsing the function in this manner naturally requires custom code, but in terms of "storing" functions in JSON, I like this way of doing it.

在上面的例子中,我有 Sass 和 JS 函数来从全局地图/对象中检索颜色值。以这种方式解析函数自然需要自定义代码,但在 JSON 中“存储”函数方面,我喜欢这种方式。