我想将JavaScript对象存储在HTML5 localStorage
,但是我的对象显然正在转换为字符串。
我可以使用localStorage
存储和检索原始JavaScript类型和数组,但是对象似乎无法正常工作。 应该吗
这是我的代码:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
console.log('typeof testObject: ' + typeof testObject);
console.log('testObject properties:');
for (var prop in testObject) {
console.log(' ' + prop + ': ' + testObject[prop]);
}
// Put the object into storage
localStorage.setItem('testObject', testObject);
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');
console.log('typeof retrievedObject: ' + typeof retrievedObject);
console.log('Value of retrievedObject: ' + retrievedObject);
控制台输出为
typeof testObject: object
testObject properties:
one: 1
two: 2
three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]
在我看来, setItem
方法在存储输入之前将输入转换为字符串。
我在Safari,Chrome和Firefox中看到了这种行为,因此我认为这是我对HTML5 Web存储规范的误解,而不是浏览器特定的错误或限制。
我试图弄清http://www.w3.org/TR/html5/infrastructure.html中描述的结构化克隆算法。 我不完全明白这是什么意思,但也许我的问题与我的对象的属性不可枚举有关(???)
有一个简单的解决方法吗?
更新:W3C最终改变了对结构化克隆规范的想法,并决定更改规范以匹配实现。 参见https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111 。 因此,此问题不再100%有效,但答案可能仍然很有趣。
#1楼
再次查看Apple , Mozilla和Mozilla文档,该功能似乎仅限于处理字符串键/值对。
一种解决方法是在存储对象之前先对其进行字符串化 ,然后在检索它时对其进行解析:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');
console.log('retrievedObject: ', JSON.parse(retrievedObject));
#2楼
您可能会发现使用以下方便的方法扩展Storage对象很有用:
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
return JSON.parse(this.getItem(key));
}
这样,即使在API下仅支持字符串,您也可以获得真正想要的功能。
#3楼
在碰到另一篇已与此副本重复的帖子之后,我到达了这篇文章。这篇文章的标题为“如何在本地存储中存储数组?”。 很好,除非两个线程都不能真正提供有关如何在localStorage中维护数组的完整答案-但是我设法根据两个线程中包含的信息制定了一个解决方案。
因此,如果其他任何人都希望能够推送/弹出/移动数组中的项目,并且他们希望将该数组存储在localStorage或sessionStorage中,则可以执行以下操作:
Storage.prototype.getArray = function(arrayName) {
var thisArray = [];
var fetchArrayObject = this.getItem(arrayName);
if (typeof fetchArrayObject !== 'undefined') {
if (fetchArrayObject !== null) { thisArray = JSON.parse(fetchArrayObject); }
}
return thisArray;
}
Storage.prototype.pushArrayItem = function(arrayName,arrayItem) {
var existingArray = this.getArray(arrayName);
existingArray.push(arrayItem);
this.setItem(arrayName,JSON.stringify(existingArray));
}
Storage.prototype.popArrayItem = function(arrayName) {
var arrayItem = {};
var existingArray = this.getArray(arrayName);
if (existingArray.length > 0) {
arrayItem = existingArray.pop();
this.setItem(arrayName,JSON.stringify(existingArray));
}
return arrayItem;
}
Storage.prototype.shiftArrayItem = function(arrayName) {
var arrayItem = {};
var existingArray = this.getArray(arrayName);
if (existingArray.length > 0) {
arrayItem = existingArray.shift();
this.setItem(arrayName,JSON.stringify(existingArray));
}
return arrayItem;
}
Storage.prototype.unshiftArrayItem = function(arrayName,arrayItem) {
var existingArray = this.getArray(arrayName);
existingArray.unshift(arrayItem);
this.setItem(arrayName,JSON.stringify(existingArray));
}
Storage.prototype.deleteArray = function(arrayName) {
this.removeItem(arrayName);
}
用法示例-将简单字符串存储在localStorage数组中:
localStorage.pushArrayItem('myArray','item one');
localStorage.pushArrayItem('myArray','item two');
用法示例-将对象存储在sessionStorage数组中:
var item1 = {}; item1.name = 'fred'; item1.age = 48;
sessionStorage.pushArrayItem('myArray',item1);
var item2 = {}; item2.name = 'dave'; item2.age = 22;
sessionStorage.pushArrayItem('myArray',item2);
操纵数组的常用方法:
.pushArrayItem(arrayName,arrayItem); -> adds an element onto end of named array
.unshiftArrayItem(arrayName,arrayItem); -> adds an element onto front of named array
.popArrayItem(arrayName); -> removes & returns last array element
.shiftArrayItem(arrayName); -> removes & returns first array element
.getArray(arrayName); -> returns entire array
.deleteArray(arrayName); -> removes entire array from storage
#4楼
一个使用localStorage跟踪来自联系人的消息的库的小示例:
// This class is supposed to be used to keep a track of received message per contacts.
// You have only four methods:
// 1 - Tells you if you can use this library or not...
function isLocalStorageSupported(){
if(typeof(Storage) !== "undefined" && window['localStorage'] != null ) {
return true;
} else {
return false;
}
}
// 2 - Give the list of contacts, a contact is created when you store the first message
function getContacts(){
var result = new Array();
for ( var i = 0, len = localStorage.length; i < len; ++i ) {
result.push(localStorage.key(i));
}
return result;
}
// 3 - store a message for a contact
function storeMessage(contact, message){
var allMessages;
var currentMessages = localStorage.getItem(contact);
if(currentMessages == null){
var newList = new Array();
newList.push(message);
currentMessages = JSON.stringify(newList);
}
else
{
var currentList =JSON.parse(currentMessages);
currentList.push(message);
currentMessages = JSON.stringify(currentList);
}
localStorage.setItem(contact, currentMessages);
}
// 4 - read the messages of a contact
function readMessages(contact){
var result = new Array();
var currentMessages = localStorage.getItem(contact);
if(currentMessages != null){
result =JSON.parse(currentMessages);
}
return result;
}
#5楼
@Guria的答案的改进:
Storage.prototype.setObject = function (key, value) {
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.getObject =