2011-05-31 47 views
102

SessionStorage和LocalStorage允许在Web浏览器中保存键/值对。该值必须是一个字符串,并且保存js对象不是微不足道的。在sessionStorage中保存Javascript对象

var user = {'name':'John'}; 
sessionStorage.setItem('user', user); 
var obj = sessionStorage.user; // obj='[object Object]' Not an object 

现在,您可以通过将对象序列化为JSON,然后反序列化它们以恢复对象来避免此限制。但是Storage API总是通过setItemgetItem方法。

sessionStorage.setItem('user', JSON.stringify(user)); 
var obj = JSON.parse(sessionStorage.getItem('user')); // An object :D 

我可以避免这种限制吗?

我只是要执行这样的事情:

sessionStorage.user.name; // 'John' 
sessionStorage.user.name = 'Mary'; 
sessionStorage.user.name // 'Mary' 

我曾尝试defineGetterdefineSetter方法拦截电话,但它是一个单调乏味的工作,因为我必须定义所有属性和我的目标是不了解未来的属性。

+1

我想到的是我自己。我想很多人都有。但我认为getter和setter方法不是一个太大的负担。 BTW;你可以使用JavaScript进行序列化和解析,并且MS最终支持与其他人一样的标准对象。像JSON和jQuery这样的软件包需求日益迅速到来。 – 2013-03-18 07:45:29

+1

我想我没有看到这个限制。如果你只有微不足道的对象,那么使用JSON.stringify和JSON.parse看起来可能过于矫枉过正,但如果你有大小适中的数据对象,那么这两种方法正在为你做很多工作。 – Robusto 2013-08-05 15:26:01

+5

“我能避免这种限制吗?”似乎是一个问题 – sonicblis 2014-06-19 21:17:46

回答

16

您可以使用Web Storage API提供的访问器,也可以编写包装器/适配器。从你声明的问题与defineGetter/defineSetter听起来像写一个包装/适配器对你来说太多的工作。

我真的不知道该告诉你什么。也许你可以重新评估一下什么是“荒谬的限制”。 Web Storage API就是它应该成为的关键/价值商店。

+4

对不起,如果我用一个不合适的词与'荒谬'。用'可能很有趣'代替它。 我认为webStorage是新网站最令人兴奋的改进之一。但只保存值键盘中的字符串我认为是一个限制。这似乎是一个饼干'续集。我知道存储是一个不仅适用于Javascript语言的规范,但序列化对象可能是一个有趣的改进。你怎么看? – 2011-06-02 09:18:31

+1

如果JSON不够,可以随时编写自己的对象序列化方法。 – 2011-06-02 14:07:34

+1

甚至违背SO规则的最愚蠢的答案。 Downvoted。 – sidney 2017-12-06 10:48:16

86

难道你不能'串化'你的对象...然后使用sessionStorage.setItem()来存储你的对象的字符串表示...然后当你需要它sessionStorage.getItem(),然后使用$.parseJSON()让它退出?

工作实例http://jsfiddle.net/pKXMa/

+0

这适用于我。在调用$ .parseJSON()后,我得到一个工作的Json对象() – 2014-11-24 15:46:49

+0

一些像Web Api认证的系统以Object {propertyOneWithoutQuotes:“”,... propertyNWithoutQuotes:“”}的形式返回对象,需要经过“stringify ”。如果有多个来源,使用stringify来标准化数据可能会更好。 – Jelgab 2015-01-28 16:55:17

+0

这是非常好的答案。使用JSON.stringify()来序列化对象并存储在sessionStorage中是很好的。然后,它使用$ .parseJSON()来反序列化字符串以获取对象。 – 2016-12-03 00:21:00

5

使用案例:

sesssionStorage.setObj(1,{date:Date.now(),action:'save firstObject'}); 
sesssionStorage.setObj(2,{date:Date.now(),action:'save 2nd object'}); 
//Query first object 
    sesssionStorage.getObj(1) 
    //Retrieve date created of 2nd object 
    new Date(sesssionStorage.getObj(1).date) 

API

Storage.prototype.setObj = function(key, obj) { 

     return this.setItem(key, JSON.stringify(obj)) 
    }; 

    Storage.prototype.getObj = function(key) { 
     return JSON.parse(this.getItem(key)) 
    }; 
+2

我认为在JavaScript中的最佳做法之一是不原型对象,你不拥有。使用Storage.prototype.setObj看起来不是一个好主意。 – britztopher 2015-01-13 15:44:42

+0

相信我。这是一个好主意,除了Object对象本身 – 2015-01-13 16:15:31

+3

只是增加了强制性..确保你不添加这个原型代码 - 并独占依赖 - 没有首先检查浏览器是否支持它存储:'if(typeof(Storage) !==“undefined”){/ *浏览器支持* /}' – JoeBrockhaus 2015-04-09 14:26:34

49

的解决方案是呼吁的sessionStorage setItem之前字符串化的对象。

var user = {'name':'John'}; 
sessionStorage.setItem('user', JSON.stringify(user)); 
var obj = JSON.parse(sessionStorage.user); 
1
var user = {'name':'John'}; 
    sessionStorage['user'] = JSON.stringify(user); 
    console.log(sessionStorage['user']); 
3

这是一个动态的解决方案,与所有的值类型,包括对象的工作原理:

class Session extends Map { 
    set(id, value) { 
    if (typeof value === 'object') value = JSON.stringify(value); 
    sessionStorage.setItem(id, value); 
    } 

    get(id) { 
    const value = sessionStorage.getItem(id); 
    try { 
     return JSON.parse(value); 
    } catch (e) { 
     return value; 
    } 
    } 
} 

然后:

const session = new Session(); 

session.set('name', {first: 'Ahmed', last : 'Toumi'}); 
session.get('name'); 
+0

不错,但不适用于函数。 – RSG 2018-02-01 14:53:34

0

你也可以用它来执行它的store library你具有交叉浏览能力。

例如:

// Store current user 
store.set('user', { name:'Marcus' }) 

// Get current user 
store.get('user') 

// Remove current user 
store.remove('user') 

// Clear all keys 
store.clearAll() 

// Loop over all stored values 
store.each(function(value, key) { 
    console.log(key, '==', value) 
})