属性:‘);for(var object in testObject){ console.log(’‘+ prop +’:’+ testObject [prop]);}
//把对象放进去 存储 </跨度> localStorage.setItem(‘testObject’,testObject);
//从中检索…对象 存储 </跨度> var retrieveObject = localStorage.getItem(‘testObject’);
console.log(‘typeof retrieveObject:’+ typeof retrieveObject);console.log(’retrieveObject的值…
有一个很棒的库可以包含许多解决方案,所以它甚至支持所谓的旧浏览器 jStorage
您可以设置一个对象
$.jStorage.set(key, value)
并轻松检索它
value = $.jStorage.get(key) value = $.jStorage.get(key, "default value")
理论上,可以存储具有以下功能的对象:
function store (a) { var c = {f: {}, d: {}}; for (var k in a) { if (a.hasOwnProperty(k) && typeof a[k] === 'function') { c.f[k] = encodeURIComponent(a[k]); } } c.d = a; var data = JSON.stringify(c); window.localStorage.setItem('CODE', data); } function restore () { var data = window.localStorage.getItem('CODE'); data = JSON.parse(data); var b = data.d; for (var k in data.f) { if (data.f.hasOwnProperty(k)) { b[k] = eval("(" + decodeURIComponent(data.f[k]) + ")"); } } return b; }
的 但是,函数序列化/反序列化是不可靠的,因为 它依赖于实现 。 强>
循环遍历localstorage
var retrievedData = localStorage.getItem("MyCart"); retrievedData.forEach(function (item) { console.log(item.itemid); });
使用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; }
我用另外20行代码制作了另一个简约包装器,允许它像它应该使用它:
localStorage.set('myKey',{a:[1,2,5], b: 'ok'}); localStorage.has('myKey'); // --> true localStorage.get('myKey'); // --> {a:[1,2,5], b: 'ok'} localStorage.keys(); // --> ['myKey'] localStorage.remove('myKey');
https://github.com/zevero/simpleWebstorage
我做了一件不破坏现有存储对象的东西,但创建了一个包装器,这样你就可以做你想做的事。结果是一个普通的对象,没有方法,可以像任何对象一样进行访问。
我做的事情。
如果你想要1 localStorage 属性是魔术:
localStorage
var prop = ObjectStorage(localStorage, 'prop');
如果你需要几个:
var storage = ObjectStorage(localStorage, ['prop', 'more', 'props']);
你所做的一切 prop 或者对象 的 内 强> storage 将自动保存到 localStorage 。你总是玩一个真实的物体,所以你可以做这样的事情:
prop
storage
storage.data.list.push('more data'); storage.another.list.splice(1, 2, {another: 'object'});
每一个新的对象 的 内 强> 将自动跟踪跟踪的对象。
的 非常大的缺点: 强> 这取决于 Object.observe() 所以它的浏览器支持非常有限。它似乎不会很快就会出现在Firefox或Edge上。
Object.observe()
我已经修改了一个最高投票的答案。如果不需要,我是单功能而不是2的粉丝。
Storage.prototype.object = function(key, val) { if ( typeof val === "undefined" ) { var value = this.getItem(key); return value ? JSON.parse(value) : null; } else { this.setItem(key, JSON.stringify(val)); } } localStorage.object("test", {a : 1}); //set value localStorage.object("test"); //get value
此外,如果未设置任何值,则返回 null 代替 false 。 false 有一些意义, null 才不是。
null
false
改进@Guria的答案:
Storage.prototype.setObject = function (key, value) { this.setItem(key, JSON.stringify(value)); }; Storage.prototype.getObject = function (key) { var value = this.getItem(key); try { return JSON.parse(value); } catch(err) { console.log("JSON parse failed for lookup of ", key, "\n error was: ", err); return null; } };
这里是@danott发布的代码的一些扩展版本
它也将实施 的 删除 强> 来自localstorage的价值 并展示了如何添加Getter和Setter层而不是
localstorage.setItem(preview, true)
你可以写
config.preview = true
好的,这里是:
var PT=Storage.prototype if (typeof PT._setItem >='u') PT._setItem = PT.setItem; PT.setItem = function(key, value) { if (typeof value >='u')//..ndefined this.removeItem(key) else this._setItem(key, JSON.stringify(value)); } if (typeof PT._getItem >='u') PT._getItem = PT.getItem; PT.getItem = function(key) { var ItemData = this._getItem(key) try { return JSON.parse(ItemData); } catch(e) { return ItemData; } } // Aliases for localStorage.set/getItem get = localStorage.getItem.bind(localStorage) set = localStorage.setItem.bind(localStorage) // Create ConfigWrapperObject var config = {} // Helper to create getter & setter function configCreate(PropToAdd){ Object.defineProperty( config, PropToAdd, { get: function () { return ( get(PropToAdd) ) }, set: function (val) { set(PropToAdd, val ) } }) } //------------------------------ // Usage Part // Create properties configCreate('preview') configCreate('notification') //... // Config Data transfer //set config.preview = true //get config.preview // delete config.preview = undefined
那么你可以删除别名部分 .bind(...) 。但是我只是把它放进去,因为知道这个真的很好。我花了几个小时才弄清楚为什么这么简单 get = localStorage.getItem; 不工作
.bind(...)
get = localStorage.getItem;
要存储对象,您可以创建一个字母,您可以使用这些字母将字符串中的对象转换为对象(可能没有意义)。例如
var obj = {a: "lol", b: "A", c: "hello world"}; function saveObj (key){ var j = ""; for(var i in obj){ j += (i+"|"+obj[i]+"~"); } localStorage.setItem(key, j); } // Saving Method function getObj (key){ var j = {}; var k = localStorage.getItem(key).split("~"); for(var l in k){ var m = k[l].split("|"); j[m[0]] = m[1]; } return j; } saveObj("obj"); // undefined getObj("obj"); // {a: "lol", b: "A", c: "hello world"}
如果你使用你用来分割对象的字母,这种技术会引起一些故障,而且它也是非常实验性的。
一个小小的改进 变种 :
Storage.prototype.setObject = function(key, value) { this.setItem(key, JSON.stringify(value)); } Storage.prototype.getObject = function(key) { var value = this.getItem(key); return value && JSON.parse(value); }
因为 短路评估 , getObject() 将 立即 返回 null 如果 key 不在存储中。它也不会抛出一个 SyntaxError 如果是例外 value 是 "" (空字符串; JSON.parse() 无法处理)。
getObject()
key
SyntaxError
value
""
JSON.parse()
似乎这里的答案并未涵盖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代码中使用。
eval()
使用的问题 JSON.stringify() 对于存储对象,该函数不能序列化私有成员。 这个问题可以通过覆盖来解决 .toString() 方法(在Web存储中存储数据时隐式调用):
JSON.stringify()
.toString()
//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 无法处理的是循环引用:
stringify
var obj = {}; obj["circular"] = obj; localStorage.object = JSON.stringify(obj); //Fails
在这个例子中, JSON.stringify() 会抛出一个 TypeError “将循环结构转换为JSON” 。 如果应该支持存储循环引用,则第二个参数为 JSON.stringify() 可能会用到:
TypeError
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; } });
但是,找到一个有效的存储循环引用的解决方案很大程度上取决于需要解决的任务,恢复这些数据也不是一件容易的事。
在处理这个问题的SO上已经存在一些问题: Stringify(转换为JSON)具有循环引用的JavaScript对象
http://rhaboo.org 是一个localStorage糖层,可以让你写这样的东西:
var store = Rhaboo.persistent('Some name'); store.write('count', store.count ? store.count+1 : 1); store.write('somethingfancy', { one: ['man', 'went'], 2: 'mow', went: [ 2, { mow: ['a', 'meadow' ] }, {} ] }); store.somethingfancy.went[1].mow.write(1, 'lawn');
它不使用JSON.stringify / parse,因为这对大对象来说是不准确和缓慢的。相反,每个终端值都有自己的localStorage条目。
你可能猜到我可能和rhaboo有关;-)
阿德里安。
看看这个
假设您有以下数组称为电影:
var movies = ["Reservoir Dogs", "Pulp Fiction", "Jackie Brown", "Kill Bill", "Death Proof", "Inglourious Basterds"];
使用stringify函数,可以使用以下语法将movies数组转换为字符串:
localStorage.setItem("quentinTarantino", JSON.stringify(movies));
请注意,我的数据存储在名为quentinTarantino的密钥下。
检索您的数据
var retrievedData = localStorage.getItem("quentinTarantino");
要将字符串转换回对象,请使用JSON解析函数:
var movies2 = JSON.parse(retrievedData);
您可以调用movies2上的所有数组方法
您可能会发现使用这些方便的方法扩展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下面只支持字符串。
更好的是你将函数设置为setter和getter 的 localStorage的 强> 这样你就可以有更好的控制权,而不必重复JSON解析。 它甚至会处理你的 的 (“”) 强> 空字符串键/数据案例顺利。
function setItemInStorage(dataKey, data){ localStorage.setItem(dataKey, JSON.stringify(data)); } function getItemFromStorage(dataKey){ var data = localStorage.getItem(dataKey); return data? JSON.parse(data): null ; } setItemInStorage('user', { name:'tony stark' }); getItemFromStorage('user'); /* return {name:'tony stark'} */
您可以使用 ejson 将对象存储为字符串。
EJSON是JSON的扩展,支持更多类型。它支持所有JSON安全类型,以及: 日期(JavaScript Date ) 二进制(JavaScript Uint8Array 或者结果 EJSON.newBinary ) 用户定义的类型(参见 EJSON.addType 。例如, Mongo.ObjectID 以这种方式实现。) 所有EJSON序列化也都是有效的JSON。例如,具有日期和二进制缓冲区的对象将在EJSON中序列化为: { "d": {"$date": 1358205756553}, "b": {"$binary": "c3VyZS4="} }
EJSON是JSON的扩展,支持更多类型。它支持所有JSON安全类型,以及:
Date
Uint8Array
所有EJSON序列化也都是有效的JSON。例如,具有日期和二进制缓冲区的对象将在EJSON中序列化为:
{ "d": {"$date": 1358205756553}, "b": {"$binary": "c3VyZS4="} }
这是我使用ejson的localStorage包装器
https://github.com/UziTech/storage.js
我在包装器中添加了一些类型,包括正则表达式和函数
看着 苹果 , 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));