LocalStorage.getItem (‘item’) è migliore di localStorage.item o localStorage ?

Recentemente ho fatto una domanda su LocalStorage . L’utilizzo di JSON.parse(localStorage.item) e JSON.parse(localStorage['item']) non funzionava per restituire NULL quando l’elemento non era ancora stato impostato.

Tuttavia, JSON.parse(localStorage.getItem('item') ha funzionato e si scopre che anche JSON.parse(localStorage.testObject || null) funziona.

Uno dei commenti in pratica diceva che localStorage.getItem() e localStorage.setItem() dovrebbero sempre essere preferiti:

Il getter e il setter forniscono un modo coerente, standardizzato e compatibile con i crossbrowser per lavorare con l’api LS e dovrebbero essere sempre preferiti rispetto agli altri modi. – Christoph

Mi è venuto in mente di usare il punto stenografico e le notazioni sulle parentesi per localStorage, ma sono curioso di sapere che cosa ne pensa l’altro. LocalStorage.getItem (‘item’) è migliore di localStorage.item o localStorage [‘item’] O finché funzionano sono le notazioni abbreviate ok?

Sia l’accesso diretto alle proprietà ( localStorage.item o localStorage['item'] ) e l’utilizzo dell’interfaccia funzionale ( getItem('item') ) funzionano bene. Entrambi sono compatibili standard e cross-browser. * Secondo le specifiche :

I nomi di proprietà supportati su un object di archiviazione sono le chiavi di ciascuna coppia chiave / valore attualmente presente nell’elenco associato all’object, nell’ordine in cui le chiavi sono state aggiunte per ultime all’area di archiviazione.

Si comportano in modo diverso quando non viene trovata alcuna coppia chiave / valore con il nome richiesto. Ad esempio, se la chiave 'item' non esiste, var a = localStorage.item; risulterà in a undefined , mentre var a = localStorage.getItem('item'); risulterà in a valore null . Come hai scoperto, undefined e null non sono intercambiabili in JavaScript / EcmaScript. 🙂

EDIT: Come Christoph indica nella sua risposta , l’interfaccia funzionale è l’unico modo per archiviare e recuperare in modo affidabile i valori sotto chiavi uguali alle proprietà predefinite di localStorage ( length , key , setItem , getItem , removeItem e clear ). Quindi, ad esempio, il seguente funzionerà sempre:

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

Si noti in particolare che la prima istruzione non influenzerà la proprietà localStorage.length (eccetto forse incrementandola se non ci fosse la chiave 'length' già in localStorage ). A questo proposito, la specifica sembra essere internamente incoerente.

Tuttavia, il seguente probabilmente non farà quello che vuoi:

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

È interessante notare che il primo è un no-op in Chrome, ma è anche sinonimo di chiamata funzionale in Firefox. Il secondo registrerà sempre il numero di chiavi presenti in localStorage .

* Questo è vero per i browser che supportano lo storage web in primo luogo. (Questo include praticamente tutti i moderni browser desktop e mobili.) Per ambienti che simulano lo storage locale utilizzando cookie o altre tecniche, il comportamento dipende dallo shim utilizzato. Diversi polyfill per localStorage possono essere trovati qui .

La domanda è già piuttosto vecchia, ma dato che sono stato citato nella domanda, penso che dovrei dire due parole sulla mia affermazione.

L’object di archiviazione è piuttosto speciale, è un object, che fornisce l’accesso a un elenco di coppie chiave / valore. Quindi non è un ordinario object o array.

Ad esempio, ha l’attributo length, che a differenza dell’attributo length array è in sola lettura e restituisce il numero di chiavi nella memoria.

Con un array puoi fare:

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

Qui abbiamo il primo motivo per usare i getter / setter. Cosa succede se si desidera impostare un articolo chiamato 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" 

Con altri membri dell’object Storage è ancora più critico, dal momento che sono scrivibili e puoi accidentalmente sovrascrivere metodi come getItem . L’utilizzo dei metodi API previene uno di questi possibili problemi e fornisce un’interfaccia coerente.

Un altro punto interessante è il seguente paragrafo nelle specifiche (sottolineato da me):

I metodi setItem () e removeItem () devono essere atomici rispetto all’errore. In caso di fallimento, il metodo non fa nulla. In altre parole, le modifiche all’area di archiviazione dei dati devono avere esito positivo oppure l’area di archiviazione dei dati non deve essere affatto modificata.

In teoria non dovrebbe esserci differenza tra i getter / setter e l’accesso [] , ma non si sa mai …

So che è un vecchio post ma poiché nessuno in realtà ha menzionato le prestazioni ho impostato alcuni test JsPerf per fare un benchmark e oltre a essere un’interfaccia coerente, getItem e setItem sono anche più veloci dell’uso di notazione o parentesi puntiforms oltre che molto più facili da leggere .

Ecco i miei test su JsPerf

Come è stato detto, non c’è quasi nessuna differenza tranne la chiave inesistente. La differenza di prestazioni varia a seconda del browser / sistema operativo in uso. Ma non è poi così diverso.

Ti suggerisco di usare l’interfaccia standard, solo perché è un modo consigliato di usarlo.