localStorage

Время чтения: меньше 5 мин

Кратко

Секция статьи "Кратко"

Это объект, хранящийся в window, который позволяет долговременно сохранять данные в браузере. Работает как хранилище данных в формате ключ-значение — при сохранении данных мы указываем имя поля, в которое должны быть сохранены данные, и затем используем это имя для их получения.

  • Значения хранятся в виде строк. При попытке сохранения других типов данных, они будут приведены к строке. Например, если записать число, то при чтении нам вернётся число, записанное в строку.
  • Не имеет ограничений по времени хранения, может быть очищен пользователем вручную или браузером при переполнении автоматически (браузеры на основе движка WebKit, например Safari, очищают localStorage, если к нему не обращались в течение 7 дней).
  • Максимальный объем данных ограничен размером 5MB.

Пример

Секция статьи "Пример"

Записываем данные:

        
          
          window.localStorage.setItem("name", "Doka Dog")
          window.localStorage.setItem("name", "Doka Dog")

        
        
          
        
      

При чтении ранее записанных данных по ключу name мы получим Doka Dog:

        
          
          const name = window.localStorage.getItem("name")console.log(name)
          const name = window.localStorage.getItem("name")
console.log(name)

        
        
          
        
      

Повторная запись по тому же ключу приведёт к замене данных:

        
          
          window.localStorage.setItem("name", "Dog Doka")const name = window.localStorage.getItem("name")console.log(name)
          window.localStorage.setItem("name", "Dog Doka")
const name = window.localStorage.getItem("name")
console.log(name)

        
        
          
        
      

Как это понять

Секция статьи "Как это понять"

Если вам нужно сохранить данные в браузере на долгое время и объем этих данных достаточно большой, то localStorage — то, что вам нужно. Данные будут храниться бессрочно и могут быть стёрты только в двух случаях: при превышении лимита по размеру данных или очистке хранилища пользователем или программно.

Как пишется

Секция статьи "Как пишется"

Запись

Секция статьи "Запись"

Для записи используйте метод setItem("ключ", "значение"), который принимает два строковых параметра: ключ, по которому будет сохранено значение, и само значение.

        
          
          window.localStorage.setItem("name", "Doka Dog")
          window.localStorage.setItem("name", "Doka Dog")

        
        
          
        
      

Чтение

Секция статьи "Чтение"

За чтение отвечает getItem("ключ") c одним параметром, который указывает на ключ для чтения и возвращает полученное значение из хранилища. Если по этому ключу нет значения, то метод вернёт null.

        
          
          window.localStorage.getItem("name") // вернет "Doka Dog"window.localStorage.getItem("user") // вернет `null`
          window.localStorage.getItem("name") // вернет "Doka Dog"
window.localStorage.getItem("user") // вернет `null`

        
        
          
        
      

Удаление

Секция статьи "Удаление"

Удаляет запись из хранилища removeItem("ключ"). Он успешно выполнится даже если указанного ключа не существует в хранилище.

        
          
          window.localStorage.removeItem("name")window.localStorage.removeItem("user")
          window.localStorage.removeItem("name")
window.localStorage.removeItem("user")

        
        
          
        
      

Очистка хранилища

Секция статьи "Очистка хранилища"

Метод clear() очищает хранилище полностью.

        
          
          window.localStorage.clear()
          window.localStorage.clear()

        
        
          
        
      

Количество полей в хранилище

Секция статьи "Количество полей в хранилище"

Используя свойство length, можно узнать, сколько всего полей было записано в хранилище.

        
          
          window.localStorage.length
          window.localStorage.length

        
        
          
        
      

Получение ключа по индексу

Секция статьи "Получение ключа по индексу"

Метод key() получает ключ по индексу. Значения в хранилище хранятся в порядке их добавления, поэтому значение, добавленное первым, будет храниться в позиции 0 и так далее.

        
          
          window.localStorage.setItem("name", "Doka Dog")window.localStorage.key(0) // вернет "name"
          window.localStorage.setItem("name", "Doka Dog")
window.localStorage.key(0) // вернет "name"

        
        
          
        
      

Таким образом, используя количество полей в хранилище и получение ключа по индексу, можно организовать перебор всех значений в хранилище.

        
          
          const localStorageSize = window.localStorage.lengthfor (let i = 0; i < localStorageSize; i++) {  console.log(window.localStorage.getItem(localStorage.key(i)))}
          const localStorageSize = window.localStorage.length
for (let i = 0; i < localStorageSize; i++) {
  console.log(window.localStorage.getItem(localStorage.key(i)))
}

        
        
          
        
      

События

Секция статьи "События"

При установке значения в хранилище срабатывает глобальное событие storage, с помощью которого можно отслеживать изменения в хранилище.

💡 Событие происходит только на других открытых страницах текущего сайта.

Событие содержит свойства:

  • key - ключ, который был изменён (при вызове метода clear(), ключ будет null);
  • oldValue - старое значение, записанное в поле;
  • newValue - новое значение, записанное в поле;
  • url - адрес страницы, на которой вызвано изменение.
        
          
          window.addEventListener("storage", function (evt) {  console.log(evt)})
          window.addEventListener("storage", function (evt) {
  console.log(evt)
})

        
        
          
        
      

На практике

Секция статьи "На практике"

akellbl4

Секция статьи "akellbl4"

🛠 При помощи localStorage можно сохранять данные, относящиеся к пользователю, не храня их на сервере. В следующем примере мы будем запоминать размер шрифта на сайте и восстанавливать размер из хранилища, если он был изменён до этого.

Открыть демо в новой вкладке

🛠 Можно использовать для синхронизации нескольких открытых в браузере вкладок. При изменении размера шрифта в одной вкладке мы узнаем об этом во всех остальных и тоже изменим размер.

        
          
          function changePageFontSize(size) {  document.style.fontSize = `${size}px`}window.addEventListener("storage", function (evt) {  if (evt.key === "pageFontSize") {    changePageFontSize(evt.newValue)  }})
          function changePageFontSize(size) {
  document.style.fontSize = `${size}px`
}

window.addEventListener("storage", function (evt) {
  if (evt.key === "pageFontSize") {
    changePageFontSize(evt.newValue)
  }
})

        
        
          
        
      

🛠 Иногда нам нужно сохранить не просто текст, а целую структуру данных, и в этом нам поможет JSON.stringify.

        
          
          const user = {  name: "Doka Dog",  avatarUrl: "mascot-doka.svg"}localStorage.setItem("user", JSON.stringify(user))
          const user = {
  name: "Doka Dog",
  avatarUrl: "mascot-doka.svg"
}

localStorage.setItem("user", JSON.stringify(user))

        
        
          
        
      

И после чтения парсим:

        
          
          function readUser() {  const userJSON = localStorage.getItem("user")  if (userJSON === null) {    return undefined  }  // Если вдруг в хранилище оказался невалидный JSON предохраняемся от этого  try {    return JSON.parse(userJSON)  } catch (e) {    localStorage.removeItem("user")    return undefined  }}
          function readUser() {
  const userJSON = localStorage.getItem("user")

  if (userJSON === null) {
    return undefined
  }

  // Если вдруг в хранилище оказался невалидный JSON предохраняемся от этого
  try {
    return JSON.parse(userJSON)
  } catch (e) {
    localStorage.removeItem("user")
    return undefined
  }
}

        
        
          
        
      

🛠 Если ваш сайт использует скрипты аналитики или другие внешние библиотеки, то они также имеют доступ к хранилищу. Поэтому лучше именовать ключи для записи в хранилище с префиксом в едином стиле. Например, при записи чего-либо на таком сайте я бы выбрал префикс YD_{название ключа}, тогда можно сгруппировать только нужные значения или отфильтровать их в инструментах разработчика.

🛠 Используйте функции-обёртки для предотвращения ошибок, связанных с неудачными попытками записи, отсутствием localStorage в браузере и дублированием кода.

        
          
          function getItem(key, value) {  try {    return window.localStorage.getItem(key)  } catch (e) {    console.log(e)  }}function setItem(key, value) {  try {    return window.localStorage.setItem(key, value)  } catch (e) {    console.log(e)  }}function setJSON(key, value) {  try {    const json = JSON.stringify(value)    setItem(key, json)  } catch (e) {    console.error(e)  }}function getJSON(key) {  try {    const json = getItem(key)    return JSON.parse(json)  } catch (e) {    console.error(e)  }}
          function getItem(key, value) {
  try {
    return window.localStorage.getItem(key)
  } catch (e) {
    console.log(e)
  }
}

function setItem(key, value) {
  try {
    return window.localStorage.setItem(key, value)
  } catch (e) {
    console.log(e)
  }
}

function setJSON(key, value) {
  try {
    const json = JSON.stringify(value)

    setItem(key, json)
  } catch (e) {
    console.error(e)
  }
}

function getJSON(key) {
  try {
    const json = getItem(key)

    return JSON.parse(json)
  } catch (e) {
    console.error(e)
  }
}