web-dev-qa-db-fra.com

LocalStorage.getItem ('item') est-il meilleur que localStorage.item ou localStorage ['item']?

J'ai récemment demandé ne question à propos de LocalStorage . Utiliser JSON.parse(localStorage.item) et JSON.parse(localStorage['item']) ne fonctionnaient pas pour renvoyer NULL lorsque l'élément n'avait pas encore été défini.

Cependant, JSON.parse(localStorage.getItem('item') a fonctionné. Et il s'avère que JSON.parse(localStorage.testObject || null) fonctionne également.

n des commentaires dit en gros que localStorage.getItem() et localStorage.setItem() devraient toujours être préférés:

Le getter et le setter fournissent un moyen cohérent, standardisé et compatible avec plusieurs navigateurs de fonctionner avec l’API LS et doivent toujours être préférés aux autres. - Christoph

J'ai fini par aimer utiliser les notations abrégées de points et de crochets pour LocalStorage, mais je suis curieux de connaître l'opinion des autres à ce sujet. Est-ce que localStorage.getItem ('item') est supérieur à localStorage.item ou localStorage ['item'] OR tant qu'ils fonctionnent, les notes abrégées sont correctes ?

75
Mark Rummel

L'accès direct aux propriétés (localStorage.item Ou localStorage['item']) Et l'utilisation de l'interface fonctionnelle (localStorage.getItem('item')) fonctionnent correctement. Les deux sont compatibles standard et multi-navigateur.* Selon la spécification :

Les noms de propriété pris en charge sur un objet Stockage sont les clés de chaque paire clé/valeur actuellement présente dans la liste associée à l'objet, dans l'ordre dans lequel les clés ont été ajoutées en dernier à la zone de stockage.

Ils se comportent simplement différemment lorsqu'aucune paire clé/valeur n'est trouvée avec le nom demandé. Par exemple, si la clé 'item' N'existe pas, var a = localStorage.item; Aura pour résultat que a sera undefined, tandis que var a = localStorage.getItem('item'); entraînera a ayant la valeur null. Comme vous l'avez découvert, undefined et null ne sont pas interchangeables en JavaScript/EcmaScript. :)

EDIT: Comme le souligne Christoph dans sa réponse , l'interface fonctionnelle est le seul moyen de stocker et de récupérer des valeurs de manière fiable sous des clés égal aux propriétés prédéfinies de localStorage. (Il y en a six: length, key, setItem, getItem, removeItem et clear. ) Ainsi, par exemple, ce qui suit fonctionnera toujours:

localStorage.setItem('length', 2);
console.log(localStorage.getItem('length'));

Notez en particulier que la première instruction n'affectera pas la propriété localStorage.length (Sauf peut-être l'incrémenter s'il n'y avait pas de clé 'length' Déjà dans localStorage). À cet égard, les spécifications semblent être incompatibles en interne.

Cependant, ce qui suit ne fera probablement pas ce que vous voulez:

localStorage.length = 2;
console.log(localStorage.length);

Fait intéressant, le premier est un no-op dans Chrome, mais est synonyme de l'appel fonctionnel dans Firefox. Le second enregistrera toujours le nombre de clés présentes dans localStorage.

*Cela est vrai pour les navigateurs qui prennent en charge le stockage Web en premier lieu. (Cela inclut à peu près tous les navigateurs de bureau et mobiles modernes.) Pour les environnements qui simulent un stockage local à l'aide de cookies ou d'autres techniques, le comportement dépend du shim utilisé. Plusieurs polyfill pour localStorage peuvent être trouvés ici .

75
Ted Hopp

La question est déjà assez ancienne, mais depuis que j'ai été cité dans la question, je pense que je devrais dire deux mots à propos de ma déclaration.

L'objet de stockage est assez spécial, c'est un objet qui donne accès à une liste de paires clé/valeur. Ainsi, ce n'est pas un objet ou un tableau ordinaire.

Par exemple, il possède l'attribut length, qui, contrairement à l'attribut length d'un tableau, est en lecture seule et renvoie le nombre de clés stockées.

Avec un tableau, vous pouvez faire:

var a = [1,2,3,4];
a.length // => 4
a.length = 2;
a // => [1,2]

Nous avons ici la première raison d’utiliser les getters/setters. Que faire si vous voulez définir un élément appelé length?

localStorage.length = "foo";
localStorage.length  // => 0
localStorage.setItem("length","foo");
// the "length" key is now only accessable via the getter method:
localStorage.length  // => 1
localStorage.getItem("length") // => "foo"

Avec les autres membres de l'objet Storage, c'est encore plus critique, car ils sont inscriptibles et vous pouvez écraser accidentellement des méthodes comme getItem. L'utilisation des méthodes de l'API évite ces problèmes et fournit une interface cohérente.

Autre point intéressant, le paragraphe suivant de la spécification (souligné par moi):

Les méthodes setItem () et removeItem () doivent être atomiques vis-à-vis de l'échec. En cas d'échec, la méthode ne fait rien. En d'autres termes, les modifications apportées à la zone de stockage de données doivent être réussies ou la zone de stockage de données ne doit pas être modifiée du tout.

Théoriquement, il ne devrait y avoir aucune différence entre les getters/setters et les [] _ accès, mais on ne sait jamais ...

10
Christoph

Je sais que c’est un vieux billet, mais comme personne n’a mentionné les performances, j’ai configuré des tests JsPerf pour le comparer et, en plus d’être une interface cohérente, getItem et setItem sont également plus rapides que la notation par points. ou entre parenthèses tout en étant beaucoup plus facile à lire.

Voici mes tests sur JsPerf

1
Dave Mackintosh

Comme il a été mentionné, il n'y a presque pas de différence sauf en ce qui concerne les clés non existantes. Le différence de performance varie en fonction du navigateur/du système d'exploitation que vous utilisez. Mais ce n'est pas vraiment si différent.

Je vous suggère d'utiliser une interface standard, simplement parce que c'est une manière recommandée de l'utiliser.

0
Salvador Dali