Подтвердить что ты не робот

Как сохранить функцию javascript в JSON

У меня есть объект JS, который я хотел бы сохранить в Local Storage для использования в будущем, и я не могу разобрать его на строку.

код:

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

Результат:

"{"a":5}"

Как сохранить его для будущего использования, если не с JSON?

(И создание моего собственного Lexer-Parser для прерывания функции строки, я не думаю, что это вариант)

4b9b3361

Ответ 1

Обычно такой вопрос указывает на проблему X/Y: вам нужно сделать X, вы думаете, что Y поможет вам это сделать, поэтому вы пытаетесь сделать Y, не можете и спросите, как сделать Y. Это часто бывает более полезно спросить, как это сделать.

Но ответ на заданный вопрос: вы могли использовать функции replacer и reviver для преобразования функции в строку (во время stringify) и обратно в функцию (во время parse), чтобы сохранить строковая версия функции, но есть всевозможные проблемы с этим, не в последнюю очередь, что область, в которой определена функция, может иметь значение для функции. (Это не имеет значения для функции, которую вы указали в вопросе, но я предполагаю, что она не является действительно репрезентативной.) И преобразование строки из локального хранилища в код, который вы можете запустить, означает, что вы доверяете, что содержимое локального хранилища hasn ' t был поврежден вредоносным способом. Предоставлено это вряд ли, если страница уже не уязвима для атак 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 eval("(" + value + ")");
  }
  return value;
});
document.body.innerHTML = obj2.b(42);

Ответ 2

Я бы рекомендовал этот подход:

Сохраните аргументы и тело в json:

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

Теперь проанализируем json и создаем экземпляр функции:

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

Я думаю, что он сохраняет

Ответ 3

Вы не можете хранить функции в JSON.

Значение в JSON может содержать только строка, число, объект, массив, true, false или null:

введите описание изображения здесь

Отметьте на сайте JSON.

Ответ 4

Один простой способ сделать это:

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

Ответ 5

Я взял имя функции вместе с значениями параметров в массиве, причем первым элементом в массиве является имя функции, добавленное с помощью $, чтобы отделить их от обычных массивов.

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

В приведенном выше примере у меня есть функции Sass и JS для извлечения значений цвета из глобальной карты/объекта. Для анализа этой функции, естественно, требуется специальный код, но с точки зрения "хранения" функций в JSON мне нравится этот способ сделать это.