一尘不染

如何在JSON中存储JavaScript函数

json

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

码:

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

结果:

"{"a":5}"

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

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


阅读 660

收藏
2020-07-27

共1个答案

一尘不染

通常,这样的问题表示X / Y问题:您需要执行X,您认为Y会帮助您完成此操作,因此您尝试执行Y,不能执行,并询问如何执行Y。这通常会更多询问如何做X很有用。

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

这是一个示例,但是除非用尽其他选项,否则我不建议您这样做,尤其是因为它使用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);

该构造(0, eval)("(" + value + ")");可确保eval在全局范围而不是在齐磊函数范围内运行。通常,它eval具有使用调用它的范围的魔术功能,但是仅在直接调用它时才有效。如图所示(或仅显示)的
间接evalvar e = eval; e("(" + value + ")");功能不具备这种魔术功能,它在全局范围内运行。

2020-07-27