preface

One of the improvements I’ve been making to the project is to extract and encapsulate some common methods. Then came the idea of packaging localStorage (localStorage).

What is localStorage?

LocalStorage is a Web Api for doing local persistent storage. LocalStorage stores data as key-value pairs. Its common methods are as follows:

/ / set
localStorage.setItem(key, val)
/ / to get
const val = localStorage.getItem(key)
/ / remove
localStorage.removeItem(key)
/ / to empty
localStorage.clear()
Copy the code

The specific functions are not introduced here.

Encapsulation localStorage

LocalStorage Api has been relatively simple and practical, then what is good packaging? My idea is mainly to solve the following points:

  • Unexpected errors that can occur when setting/getting
  • The values set/obtained are all strings, which are inconvenient to use directly.
  • Didn’t likecookieSame expiration time limit

Ok, not much to say, direct masturbation code:

const ls = window.localStorage
/ / set
const setItem = (key, val, expired) = > {
// Expired takes milliseconds
  try {
    const data = {
      [key]: val,
    }
    if (expired) {
      data[` __${key}__expired`] = Date.now() + expired
    }
    ls.setItem(key, JSON.stringify(data))
  } catch (e) {
    console.log('setItem error', e)
  }
}
/ / to get
const getItem = key= > {
  try {
    const data = JSON.parse(ls.getItem(key))
    if(! data)return
    if (data.hasOwnProperty(` __${key}__expired`)) {
      if (data[` __${key}__expired`] > =Date.now()) {
        return data[key]
      }
      removeItem(key)
      return
    }
    return data[key]
  } catch (e) {
    console.log('getItem error', e)
  }
}
/ / remove
const removeItem = key= > {
  ls.removeItem(key)
}
/ / to empty
const clear = () = > {
  ls.clear()
}

export default { setItem, getItem, removeItem, clear }
Copy the code

Not much explanation, not much logic, right

You may not know about localStorage

We all know that localStorage is part of HTML5 Web storage, HTML5 Web storage is stored in the form of key/value pair, the key/value pair collection is not the Object? What is the relationship between localStorage and Object?

LocalStorage inherits Storage, and Storage inherits Object. Their prototype chain relationship is:

localStorage.__proto__ === Storage.prototype

Storage.prototype.__proto__ === Object.prototype
Copy the code
  • Since inherited fromObjectYou can definitely use some object methods
// You can use hasOwnProperty to determine whether the key is stored
localStorage.hasOwnProperty('name') = = =true
localStorage.hasOwnProperty('name1') = = =false
Copy the code
  • You can useObject.keysGet a traversable set of keys
Object.keys(localStorage) // ["b", "name", "age", "a"]
Copy the code
  • localStorageThere arelengthProperty that represents the number of keys/values stored
/ / the number of
localStorage.length / / 2
Copy the code
  • You can use dot syntax. Or in brackets []localStorageStored values in?
/ / set
localStorage.name = 'zhangsan' 
localStorage['age'] = 19 

/ / to get
localStorage.name // 'zhangsan'
localStorage.age / / '19'
Copy the code

So you can just use dot syntax. Or brackets [], why setItem, getItem? Keep exploring.

const str = 'string'
const obj = { obj: 'obj'}
const s = Symbol('s')

localStorage.setItem(str,'string1') // string => 'string1'
localStorage[str] = 'string2' // string => 'string2'
// The same key name is overwritten

localStorage.setItem(obj,'obj1') // [object Object] => 'obj1'
localStorage[obj] = 'obj2' // [object Object] => 'obj2'
localStorage.setItem(obj,obj) // [object Object] => '[object Object]'
localStorage[obj] = obj // [object Object] => '[object Object]'
// The same key name is overwritten

localStorage.setItem(s,'symbol') // TypeError: Cannot convert a Symbol value to a string
localStorage[s] = 'symbol' // Symbol(s) => 'symbol'
Copy the code

Here we know that the key and val in setItem(key,val) methods must be strings or other types that can be converted to strings. Setting with setItem() fails when the key is of type symbol, but succeeds when setting with brackets [].

Did it work?

localStorage.getItem(s) // TypeError: Cannot convert a Symbol value to a string
// The error here should be the reason why s cannot be converted to a string.


localStorage[s] // "symbol"
/ / according to? Shouldn't localStorage keys be strings only?
Copy the code

In doubt…

Let’s try to check localStorage, as shown below:

As printed, the Symbol(s) key is present in the localStorage object, but the Length property is not changed by the addition of the Symbol(s) key.

Look again at the browser Application:

Why is there no Symbol(s) key? An idea popped into my head to refresh my browser.

Whoa, whoa, whoa… I seem to understand

conclusion

The key of the object can be of type Symbol, and localStorage is also an object. Therefore, you can add a Symbol key to localStorage using brackets.

But what’s the point of localStorage? Persistent storage! Symbol keys cannot persist. This is probably why setItem and getItem interfaces are recommended.