Ответ 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);