Stringify并不能解决所有问题
似乎这里的答案并未涵盖JavaScript中可能的所有类型,因此这里有一些关于如何正确处理它们的简短示例://Objects and Arrays:
var obj = {key: "value"};
localStorage.object = JSON.stringify(obj); //Will ignore private members
obj = JSON.parse(localStorage.object);//Boolean:
var bool = false;
localStorage.bool = bool;
bool = (localStorage.bool === "true");//Numbers:
var num = 42;
localStorage.num = num;
num = +localStorage.num; //short for "num = parseFloat(localStorage.num);"//Dates:
var date = Date.now();
localStorage.date = date;
date = new Date(parseInt(localStorage.date));//Regular expressions:
var regex = /^No\.[\d]*$/i; //usage example: "No.42".match(regex);
localStorage.regex = regex;
var components = localStorage.regex.match("^/(.*)/([a-z]*)$");
regex = new RegExp(components[1], components[2]);//Functions (not recommended):
function func(){}
localStorage.func = func;
eval( localStorage.func ); //recreates the function with the name "func"
我不建议存储函数,因为eval()邪恶会导致安全性,优化和调试问题。一般来说,eval()永远不应该在JavaScript代码中使用。
私人会员
使用JSON.stringify()存储对象的问题是,此函数无法序列化私有成员。可以通过覆盖.toString()方法(在Web存储中存储数据时隐式调用)来解决此问题://Object with private and public members:
function MyClass(privateContent, publicContent){
var privateMember = privateContent || "defaultPrivateValue";
this.publicMember = publicContent || "defaultPublicValue";
this.toString = function(){
return '{"private": "' + privateMember + '", "public": "' + this.publicMember + '"}';
};
}
MyClass.fromString = function(serialisedString){
var properties = JSON.parse(serialisedString || "{}");
return new MyClass( properties.private, properties.public );
};//Storing:
var obj = new MyClass("invisible", "visible");
localStorage.object = obj;//Loading:
obj = MyClass.fromString(localStorage.object);
循环参考
另一个问题stringify是无法处理循环引用:var obj = {};obj["circular"] = obj;localStorage.object = JSON.stringify(obj); //Fails
在此示例中,JSON.stringify()将抛出TypeError “将循环结构转换为JSON”。如果应支持存储循环引用,则JSON.stringify()可以使用第二个参数:var obj = {id: 1, sub: {}};obj.sub["circular"] = obj;localStorage.object = JSON.stringify( obj, function( key, value) {
if( key == 'circular') {
return "$ref"+value.id+"$";
} else {
return value;
}});
但是,找到一个有效的存储循环引用的解决方案很大程度上取决于需要解决的任务,恢复这些数据也不是一件容易的事。