Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 一个简单的同步locaStorage和保持js类型的方法?_Javascript_Local Storage - Fatal编程技术网

Javascript 一个简单的同步locaStorage和保持js类型的方法?

Javascript 一个简单的同步locaStorage和保持js类型的方法?,javascript,local-storage,Javascript,Local Storage,我有一个可以向localStorage写入数据和从中读取数据的应用程序 基本上,我有一个对象数组,我在代码中多次更改和读取这些对象,所有这些更改我都希望与localStorage保持同步 现在,我可以创建一个函数,每当我在代码中需要它时,它都会同步,但对我来说,它听起来有点难看,而且没有优化。像这样 arrayOfObjects.push(newItem); localStorage.setItem('objects', arrayOfObjects); 然后 arrayOfObjects =

我有一个可以向localStorage写入数据和从中读取数据的应用程序

基本上,我有一个对象数组,我在代码中多次更改和读取这些对象,所有这些更改我都希望与localStorage保持同步

现在,我可以创建一个函数,每当我在代码中需要它时,它都会同步,但对我来说,它听起来有点难看,而且没有优化。像这样

arrayOfObjects.push(newItem);
localStorage.setItem('objects', arrayOfObjects);
然后

arrayOfObjects = localStorage.getItem('objects');
length = arrayOfObjects.length
这将非常糟糕,因为我必须在代码中读写数百次,这是一个糟糕的解决方案

现在我还可以将它封装到一个函数中,以便所有的写入、读取和同步都通过它,但它仍然缺少许多功能,因为我仍然需要将arrayOfObjects作为数组类型来处理多个数组操作,如.push和.length


关于如何使此阵列与localStorage以尽可能少的代码行同步,有什么想法吗?有什么方法可以直接在localStorage中写入/读取数组类型吗?

您可以创建自己的
,该类扩展了本机
数组
,唯一的区别是在执行操作时也会将其保存

当你想还原这个特殊的
数组
时,你只需要调用它的
.restore()
方法,它基本上是从本地存储中还原回来的

下面是一个例子:

class LocalArray extends Array {
  constructor(name, ...items) {
    super(...items)
    this._name = name
  }

  push(item) {
    Array.prototype.push.call(this, item)

    this._save()
  }

  pop() {
    const popped = Array.prototype.pop.call(this)

    this._save()

    return popped
  }

  // rest of operations, i.e splice, reduce, etc..

  restore() {
    const data = window.localStorage.getItem(this._name)
    const items = data ? JSON.parse(data) : []

    items.forEach(item => {
      Array.prototype.push.call(this, item)
    })
  }

  _save() {
    window.localStorage.setItem(this._name, JSON.stringify(this))
  }
}
这就是它的使用方式:

const users = new LocalArray('users')
users.push({ name: 'John Doe' })
users.push({ name: 'Mary Jane' })
users.pop()
可以想象,LocalStorage现在将包含一个项
“用户”:[{“名称”:“John Doe”}]

。。以及恢复:

const users = new LocalArray('users')
users.restore()

console.log(users) // logs [{ name: 'John Doe' }]
请记住,这里有重要的性能影响。 例如,每次
.push()
时,都会在不断增长的阵列上触发
\u save()

您可以通过将增量(更改)保存到本地存储(而不是整个对象)中的阵列来改善这一点,但从那时起,事情开始变得复杂起来


明智地使用。

但对我来说,这听起来有点难看和不优化
你确定这不是过早的优化吗?我个人会说做一个
sync
函数来完成这项工作,看看它是否会影响性能。如果是这样,那么您可以对其进行优化,但一旦界面出现,您只需更改
sync
而无需其他操作。例如,您可以使用函数,这可能就是您所需要的全部。或者是别的什么。如果不知道用例的具体性能配置文件,很难说。很抱歉,我的意思不是在性能方面进行优化,而是在总体代码可读性和维护方面进行优化。在这种情况下,您也可以这样做-通过调用函数对阵列进行所有“更改”,因此,您永远不会直接与数组交互——这意味着您可以在其中添加任何您想要的逻辑,包括将数组持久化到locastorage。或者,您可以将阵列设置为可观察阵列,并在任何更改时附加与本地存储同步的观察者。这可能是
代理
更合适的情况之一。子类化在这里并没有真正意义。@Bergi“并没有真正意义”是一个非常有力和不恰当的陈述。代理可能是另一种选择,但这仍然是一种可行的解决方案。虽然这是你的特权,但我更希望你能写下描述你的备选解决方案的答案,而不是在你认为不完美的答案上留下深思熟虑的评论。我喜欢你的解决方案,但我也有兴趣学习如何使用代理,想法?如果将来有人寻找使用代理的解决方案:@NicholasKyriakides子类化是不可行的,如果你想检测
const users=new LocalArray('users');用户[0]={name:'John Doe'};用户[1]={name:'Mary Jane'}和许多其他的。