web-dev-qa-db-fra.com

Stockage d'objets dans le stockage local HTML5

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.

2331
Kristopher Johnson

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));
2963
CMS

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).

604
Guria

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.

211
Justin Voskuhl

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;
  }
}
70
Alex Grande

Stringify ne résout pas tous les problèmes

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.

Membres privés

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);

Références circulaires

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

63
maja

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")
51
JProgrammer

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"];
34
Shujaath Khan

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 .

28
aster_x

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);
  }
}
23
danott

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
21
Andy Lorenz

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:

13
doublejosh

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'} */
11
sheelpriy

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.

8
pie6k

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;
    }
};
6
seanp2k

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.

5
Mac

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:

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.

4
Tony Brix

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).

persisto features

(Avertissement: je suis l'auteur.)

4
mar10

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');

https://github.com/zevero/simpleWebstorage

3
zevero

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.

3
Adrian May

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);
    }
}

Exemple d'utilisation :

// 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");
2
Flavien Volken

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

1
Nadu

Regardez ceci

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

1
shas

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.

1
Seizefire

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;
 }
1
Thomas

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.

La chose que j'ai faite.

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.

1
Rudie

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);
0
Mohammad Ayoub Khan

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
0