我正在处理一些包含大量数据的对象,这些数据要在浏览器中显示和操作,我想将其保存在本地存储中。 为了保存对象,我使用了JSON.stringify(),所以一切都变成了文本,而且效果很好
{
"bindingRef": [],
"primo": {
"name": "primo",
"modifiable": true,
"binded": false,
"isInteger": false,
"label": "Numero di Primi"
},
"secondo": {
"name": "secondo",
"modifiable": true,
"binded": false,
"isInteger": false,
"label": "Numero di Secondi"
}
}
现在我试图通过将函数转换为字符串然后保存它来保存函数
JSON.stringify(myFunction.toString());
但输出是
"savedFunction": "function () {\n\t\t\t\tvar tot = menu.primo.get() * 6 + menu.secondo.get() * 8 + menu.dolce.get() * 4;\n\t\t\t\tif (menu.sconto.get()) {\n\t\t\t\t\treturn tot * 0.90;\n\t\t\t\t} else {\n\t\t\t\t\treturn tot;\n\t\t\t\t}\n\t\t\t}"
将功能保存在本地存储中是否正确?还是有更好的方法吗?如果这是正确的方法,有没有办法简单地删除任何制表符/缩进字符或我应该操纵字符串,例如使用一些正则表达式函数?
答案 0 :(得分:6)
JS中的函数与许多函数式语言一样是闭包:它们在定义时包含了环境范围内容,包括db或文件句柄等短暂数据。
这不是一个好主意,因为这会因JSON反序列化行为而导致问题,因此您必须检查函数中包含的内容以及自定义的内容。
有关详细信息,另请参阅此SO thread。
答案 1 :(得分:1)
您可以将该函数放在一个对象中,并使用我创建的函数storage.set和storage.get而不是localStorage.set和localStorage.get (localStorage不允许添加函数,这与JSON不同)
storage.set将在使用localStorage.setItem()之前对包含函数的对象进行字符串化 storage.get将在使用localStorage.getItem()后解析包含函数的对象。
我修改了函数JSON.stringify和JSON.parse以便能够处理函数,因此您可以在代码的其他部分使用它而无需更改函数名称。我在原始函数中添加了2,因此我可以在更新的函数中使用它们。
JSON.stringify2 = JSON.stringify;
JSON.parse2 = JSON.parse;
JSON.stringify = function(value) {
return JSON.stringify2(value, function(key, val) {
return (typeof val === 'function') ? val.toString().replace(/\t|\n/g, '') : val;
});
}
JSON.parse = function(value) {
return JSON.parse2(value, function(key, val) {
if (typeof val === 'string') {
var regex = /^function\s*\([^()]*\)\s*{.*}$/;
if (regex.exec(val) !== null)
return eval('key = ' + val);
else
return val;
} else
return val;
});
}
var storage = {};
storage.set = function(key, value) {
if (typeof value === 'object')
value = JSON.stringify(value);
localStorage.setItem(key, value);
}
storage.get = function(key) {
var value = localStorage.getItem(key);
try {
return JSON.parse(value);
} catch (e) {
return value;
}
}