Je voudrais stocker un objet JavaScript dans HTML5 localStorage
, mais mon objet est apparemment converti en chaîne.
Je peux stocker et récupérer des types et des tableaux JavaScript primitifs à l'aide de localStorage
, mais les objets ne semblent pas fonctionner. Devraient-ils?
Voici mon code:
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);
La sortie de la console est
typeof testObject: object
testObject properties:
one: 1
two: 2
three: 3
typeof retrievedObject: string
Value of retrievedObject: [object Object]
Il me semble que la méthode setItem
convertit l’entrée en chaîne avant de la stocker.
Je constate ce comportement dans Safari, Chrome et Firefox. Je suppose donc que c'est une erreur de compréhension de la spécification HTML5 Web Storage , et non un bogue ou une limitation spécifique au navigateur.
J'ai essayé de donner un sens à l'algorithme de clone structuré décrit dans http://www.w3.org/TR/html5/ infrastructure.html . Je ne comprends pas tout à fait ce que ça dit, mais peut-être que mon problème a à voir avec les propriétés de mon objet qui ne sont pas énumérables (???)
Existe-t-il une solution de contournement facile?
Mise à jour: le W3C a finalement changé d'avis sur la spécification des clones structurés et a décidé de modifier les spécifications pour les faire correspondre aux implémentations. Voir https://www.w3.org/Bugs/Public/show_bug.cgi?id=12111 . Donc, cette question n’est plus valable à 100%, mais les réponses pourraient quand même vous intéresser.
En regardant la documentation Apple , Mozilla et Mozilla , la fonctionnalité semble être limitée à la gestion des paires clé/valeur de chaîne.
Une solution de contournement peut consister à stringify votre objet avant de le stocker, puis de l'analyser lorsque vous le récupérez:
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));
Une amélioration mineure sur un variante :
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);
}
En raison de évaluation de court-circuit , getObject()
retournera immédiatement null
si key
n'est pas en stockage. Elle ne lève pas non plus d'exception SyntaxError
si value
est ""
(la chaîne vide; JSON.parse()
ne peut pas le gérer).
Vous trouverez peut-être utile d'étendre l'objet Storage avec ces méthodes pratiques:
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
return JSON.parse(this.getItem(key));
}
De cette façon, vous obtenez la fonctionnalité que vous souhaitiez réellement, même si sous l'API, seules les chaînes sont prises en charge.
L'extension de l'objet Storage est une solution géniale. Pour mon API, j'ai créé une façade pour localStorage, puis je vérifie s'il s'agit d'un objet ou non lors de la configuration et de l'obtention.
var data = {
set: function(key, value) {
if (!key || !value) {return;}
if (typeof value === "object") {
value = JSON.stringify(value);
}
localStorage.setItem(key, value);
},
get: function(key) {
var value = localStorage.getItem(key);
if (!value) {return;}
// assume it is an object that has been stringified
if (value[0] === "{") {
value = JSON.parse(value);
}
return value;
}
}
Il semble que les réponses ici ne couvrent pas tous les types possibles en JavaScript, voici donc quelques exemples pour vous aider à les traiter correctement:
//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"
Je ne recommande pas de stocker des fonctions car eval()
is evil peut conduire à des problèmes de sécurité, d'optimisation et de débogage. En général, eval()
ne devrait jamais être utilisé dans du code JavaScript.
Le problème lié à l'utilisation de JSON.stringify()
pour stocker des objets est que cette fonction ne peut pas sérialiser les membres privés. Ce problème peut être résolu en écrasant la méthode .toString()
(appelée implicitement lors du stockage de données dans le stockage 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);
Un autre problème que stringify
ne peut pas traiter est une référence circulaire:
var obj = {};
obj["circular"] = obj;
localStorage.object = JSON.stringify(obj); //Fails
Dans cet exemple, JSON.stringify()
lève une TypeError
"Conversion de structure circulaire en JSON" . Si le stockage des références circulaires doit être pris en charge, le deuxième paramètre de JSON.stringify()
peut être utilisé:
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;
}
});
Cependant, trouver une solution efficace pour stocker les références circulaires dépend fortement des tâches à résoudre, et la restauration de telles données n'est pas non plus triviale.
Il y a déjà quelques questions sur SO concernant ce problème: Stringify (convertir en JSON) un objet JavaScript avec une référence circulaire
Il existe une excellente bibliothèque qui englobe de nombreuses solutions, de sorte qu'elle prend même en charge les anciens navigateurs appelés jStorage
Vous pouvez définir un objet
$.jStorage.set(key, value)
Et récupérez-le facilement
value = $.jStorage.get(key)
value = $.jStorage.get(key, "default value")
Utilisation d'objets JSON pour le stockage local:
//ENSEMBLE
var m={name:'Hero',Title:'developer'};
localStorage.setItem('us', JSON.stringify(m));
//OBTENIR
var gm =JSON.parse(localStorage.getItem('us'));
console.log(gm.name);
// Itération de toutes les clés et valeurs de stockage locales
for (var i = 0, len = localStorage.length; i < len; ++i) {
console.log(localStorage.getItem(localStorage.key(i)));
}
// EFFACER
localStorage.removeItem('us');
delete window.localStorage["us"];
En théorie, il est possible de stocker des objets avec des fonctions:
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;
}
Cependant, la sérialisation/désérialisation d'une fonction n'est pas fiable car elle dépend de la mise en œuvre .
Vous pouvez également remplacer les méthodes par défaut Storage setItem(key,value)
et getItem(key)
pour gérer les objets/tableaux comme tout autre type de données. De cette façon, vous pouvez simplement appeler localStorage.setItem(key,value)
et localStorage.getItem(key)
comme vous le feriez normalement.
Je n'ai pas testé cela de manière approfondie, mais cela semble fonctionner sans problème pour un petit projet avec lequel j'ai bricolé.
Storage.prototype._setItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value)
{
this._setItem(key, JSON.stringify(value));
}
Storage.prototype._getItem = Storage.prototype.getItem;
Storage.prototype.getItem = function(key)
{
try
{
return JSON.parse(this._getItem(key));
}
catch(e)
{
return this._getItem(key);
}
}
Je suis arrivé à ce message après avoir cliqué sur un autre message qui a été fermé en tant que duplicata de celui-ci - intitulé "Comment stocker un tableau dans le stockage local?". Ce qui est correct, sauf qu'aucun fil ne fournit en réalité une réponse complète quant à la manière de gérer un tableau dans localStorage. Cependant, j'ai réussi à concevoir une solution basée sur les informations contenues dans les deux threads.
Donc, si quelqu'un d'autre veut pouvoir envoyer/déplacer/déplacer des éléments dans un tableau et qu'il souhaite que ce tableau soit stocké dans localStorage ou même dans sessionStorage, voici ce que vous devez faire:
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);
}
exemple d'utilisation - stockage de chaînes simples dans un tableau localStorage:
localStorage.pushArrayItem('myArray','item one');
localStorage.pushArrayItem('myArray','item two');
exemple d'utilisation - stockage d'objets dans le tableau 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);
méthodes courantes pour manipuler des tableaux:
.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
Il est recommandé d’utiliser une bibliothèque d’abstractions pour la plupart des fonctionnalités présentées ici, ainsi que pour une meilleure compatibilité. Beaucoup d'options:
Vous feriez mieux de créer des fonctions en tant que setter et getter localStorage, de cette manière, vous aurez un meilleur contrôle et vous ne devrez pas répéter l'analyse JSON, etc. il va même gérer votre ("")) chaîne vide clé/cas de données en douceur.
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'} */
J'ai modifié l'une des réponses les plus votées. Je suis fan d'avoir une seule fonction au lieu de 2 si ce n'est pas nécessaire.
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
De plus, si aucune valeur n'est définie, elle renvoie null
au lieu de false
. false
a un sens, null
pas.
Amélioration de la réponse de @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;
}
};
Vous pouvez utiliser localDataStorage pour stocker de manière transparente des types de données JavaScript (Array, Boolean, Date, Float, Integer, String et Object). Il fournit également une obfuscation de données légère, compresse automatiquement les chaînes, facilite la requête par clé (nom) ainsi que la requête par clé (clé), et aide à appliquer le stockage partagé segmenté au sein du même domaine en préfixant les clés.
[DISCLAIMER] Je suis l'auteur de l'utilitaire [/ DISCLAIMER]
Exemples:
localDataStorage.set( 'key1', 'Belgian' )
localDataStorage.set( 'key2', 1200.0047 )
localDataStorage.set( 'key3', true )
localDataStorage.set( 'key4', { 'RSK' : [1,'3',5,'7',9] } )
localDataStorage.set( 'key5', null )
localDataStorage.get( 'key1' ) --> 'Belgian'
localDataStorage.get( 'key2' ) --> 1200.0047
localDataStorage.get( 'key3' ) --> true
localDataStorage.get( 'key4' ) --> Object {RSK: Array(5)}
localDataStorage.get( 'key5' ) --> null
Comme vous pouvez le constater, les valeurs primitives sont respectées.
Vous pouvez utiliser ejson pour stocker les objets sous forme de chaînes.
EJSON est une extension de JSON qui prend en charge plusieurs types. Il prend en charge tous les types JSON-safe, ainsi que:
- Date (JavaScript
Date
)- Binaire (JavaScript
Uint8Array
] ou le résultat de EJSON.newBinary )- Types définis par l'utilisateur (voir EJSON.addType . Par exemple, Mongo.ObjectID est implémenté de cette façon.)
Toutes les sérialisations EJSON sont également des JSON valides. Par exemple, un objet avec une date et un tampon binaire serait sérialisé dans EJSON en tant que:
{ "d": {"$date": 1358205756553}, "b": {"$binary": "c3VyZS4="} }
Voici mon wrapper localStorage utilisant ejson
https://github.com/UziTech/storage.js
J'ai ajouté quelques types à mon emballage, notamment des expressions régulières et des fonctions.
Une autre option serait d'utiliser un plugin existant.
Par exemple, persisto est un projet open source qui fournit une interface simple à localStorage/sessionStorage et automatise la persistance des champs de formulaire (entrée, boutons d'option et cases à cocher).
(Avertissement: je suis l'auteur.)
J'ai créé un autre wrapper minimaliste avec seulement 20 lignes de code pour permettre de l'utiliser comme il se doit:
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');
http://rhaboo.org est une couche de sucre localStorage qui vous permet d'écrire des choses comme celle-ci:
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');
Il n'utilise pas JSON.stringify/parse car cela serait inexact et lent sur les gros objets. Au lieu de cela, chaque valeur de terminal a sa propre entrée localStorage.
Vous pouvez probablement deviner que je pourrais avoir quelque chose à voir avec rhaboo ;-)
Adrian.
Pour les utilisateurs de TypeScript souhaitant définir et obtenir des propriétés typées:
/**
* Silly wrapper to be able to type the storage keys
*/
export class TypedStorage<T> {
public removeItem(key: keyof T): void {
localStorage.removeItem(key);
}
public getItem<K extends keyof T>(key: K): T[K] | null {
const data: string | null = localStorage.getItem(key);
return JSON.parse(data);
}
public setItem<K extends keyof T>(key: K, value: T[K]): void {
const data: string = JSON.stringify(value);
localStorage.setItem(key, data);
}
}
// write an interface for the storage
interface MyStore {
age: number,
name: string,
address: {city:string}
}
const storage: TypedStorage<MyStore> = new TypedStorage<MyStore>();
storage.setItem("wrong key", ""); // error unknown key
storage.setItem("age", "hello"); // error, age should be number
storage.setItem("address", {city:"Here"}); // ok
const address: {city:string} = storage.getItem("address");
Voici une version étendue du code posté par @danott
Il va également implémenter supprimer valeur de localstorage et montre comment ajouter un calque Getter et Setter afin de remplacer
localstorage.setItem(preview, true)
tu peux écrire
config.preview = true
Ok, on y va:
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
Eh bien, vous pouvez supprimer la partie alias avec .bind(...)
. Cependant, je viens de le mettre car c'est vraiment bon de savoir à ce sujet. Je m’ai pris des heures pour comprendre pourquoi un simple get = localStorage.getItem;
ne fonctionne pas
Disons que vous avez le tableau suivant appelé films:
var movies = ["Reservoir Dogs", "Pulp Fiction", "Jackie Brown",
"Kill Bill", "Death Proof", "Inglourious Basterds"];
À l'aide de la fonction stringify, votre tableau de films peut être transformé en chaîne en utilisant la syntaxe suivante:
localStorage.setItem("quentinTarantino", JSON.stringify(movies));
Notez que mes données sont stockées sous la clé appelée quentinTarantino.
Récupération de vos données
var retrievedData = localStorage.getItem("quentinTarantino");
Pour reconvertir une chaîne en objet, utilisez la fonction d'analyse JSON:
var movies2 = JSON.parse(retrievedData);
Vous pouvez appeler toutes les méthodes de la matrice sur vos films2
Pour stocker un objet, vous pouvez créer une lettre que vous pouvez utiliser pour obtenir un objet d'une chaîne en un objet (cela n'a peut-être pas de sens). Par exemple
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"}
Cette technique causera quelques problèmes si vous utilisez la lettre que vous avez utilisée pour scinder l'objet, et c'est également très expérimental.
Un petit exemple de bibliothèque qui utilise localStorage pour garder une trace des messages reçus de contacts:
// 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;
}
J'ai créé quelque chose qui ne casse pas les objets de stockage existants, mais crée un wrapper afin que vous puissiez faire ce que vous voulez. Le résultat est un objet normal, pas de méthode, avec un accès comme n'importe quel objet.
Si vous voulez que la propriété 1 localStorage
soit magique:
var prop = ObjectStorage(localStorage, 'prop');
Si vous avez besoin de plusieurs:
var storage = ObjectStorage(localStorage, ['prop', 'more', 'props']);
Tout ce que vous faites pour prop
, ou les objets à l'intérieur de storage
seront automatiquement enregistrés dans localStorage
. Vous jouez toujours avec un objet réel, vous pouvez donc faire des choses comme celle-ci:
storage.data.list.Push('more data');
storage.another.list.splice(1, 2, {another: 'object'});
Et chaque nouvel objet à l'intérieur d'un objet suivi sera automatiquement suivi.
Le très gros inconvénient: cela dépend de Object.observe()
, de sorte que la prise en charge du navigateur est très limitée. Et il ne semble pas que cela arrive bientôt pour Firefox ou Edge.
J'ai cet objet JS * Je veux le stocker dans stockage local HTML5
todosList = [
{ id: 0, text: "My todo", finished: false },
{ id: 1, text: "My first todo", finished: false },
{ id: 2, text: "My second todo", finished: false },
{ id: 3, text: "My third todo", finished: false },
{ id: 4, text: "My 4 todo", finished: false },
{ id: 5, text: "My 5 todo", finished: false },
{ id: 6, text: "My 6 todo", finished: false },
{ id: 7, text: "My 7 todo", finished: false },
{ id: 8, text: "My 8 todo", finished: false },
{ id: 9, text: "My 9 todo", finished: false }
];
Je peux stocker ceci dans stockage local HTML5 de cette manière, en utilisant JSON.stringify
localStorage.setItem("todosObject", JSON.stringify(todosList));
Et maintenant, je peux obtenir cet objet du stockage local par JSON.parsing.
todosList1 = JSON.parse(localStorage.getItem("todosObject"));
console.log(todosList1);
Localstorage ne peut stocker que des paires clé-valeur où les deux clés et les valeurs doivent être des chaînes. Cependant, vous pouvez stocker des objets en les sérialisant sur des chaînes JSON
, puis en les désérialisant en objets JS lorsque vous les récupérez.
Par exemple:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
// JSON.stringify turns a JS object into a JSON string, thus we can store it
localStorage.setItem('testObject', JSON.stringify(testObject));
// After we recieve a JSON string we can parse it into a JS object using JSON.parse
var jsObject = JSON.parse(localStorage.getItem('testObject'));
Soyez conscient du fait que cela supprimera la chaîne de prototypes établie. Ceci est mieux démontré par un exemple:
function testObject () {
this.one = 1;
this.two = 2;
this.three = 3;
}
testObject.prototype.hi = 'hi';
var testObject1 = new testObject();
// logs the string hi, derived from prototype
console.log(testObject1.hi);
// the prototype of testObject1 is testObject.prototype
console.log(Object.getPrototypeOf(testObject1));
// stringify and parse the js object, will result in a normal JS object
var parsedObject = JSON.parse(JSON.stringify(testObject1));
// the newly created object now has Object.prototype as its prototype
console.log(Object.getPrototypeOf(parsedObject) === Object.prototype);
// no longer is testObject the prototype
console.log(Object.getPrototypeOf(parsedObject) === testObject.prototype);
// thus we cannot longer access the hi property since this was on the prototype
console.log(parsedObject.hi); // undefined