2

我将项目从一个数组移动到另一个数组,只要它不存在,然后将其存储在localStorage

var queue = [];

function moveToQueue(item) {
    if(queue.indexOf(item) == -1) {
        queue.push(item);
        store();
    }
}

function store() {
    localStorage.myApp_queue = JSON.stringify(queue);
}

当页面加载时,我调用我的加载函数。

function load() {
    if(typeof localStorage.myApp_queue != 'undefined') {
        queue = JSON.parse(localStorage.myApp_queue);
    }
}

此时,我的界面显示queue我上次离开时​​的样子,但如果我再次尝试添加相同的项目,“queue.indexOf(item)”将失败。的内容与调用方法queue之前的内容不同。store()/load()

console.log()以下是我的页面重新加载前后的一些调用,以空的queue. 日志已添加到moveToQueue函数的开头

function moveToQueue(item) {
    console.log('adding to queue');
    console.log(item);
    console.log(queue[0]);
    console.log(queue.indexOf(item));
    ...

初始负载:

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
undefined
-1

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
e {id: 1, status: "A", title: "Comcar", $$hashKey: "004", $get: function…}
0 

页面刷新后 - 我推送的项目已经在queue数组中

adding to queue
e {id: 1, status: "A", title: "Comcar", $$hashKey: "006", $get: function…}
Object {id: 1, status: "A", title: "Comcar", $$hashKey: "004"}
-1

我在这里错过了什么,改变我的阵列是什么localStorage以及正在做什么。JSON

我可以看到日志将从存储返回的项目列为“对象”,而原始项目的“类型”(不太确定)“e”。

如果我typeof对两者都使用结果是“对象”

4

2 回答 2

3

indexOf如果它们是对象,将通过引用比较值,因此您的代码不适用于复杂对象(即散列、字典或其他)。如果您使用检查对象是否相等的函数,您甚至可以使您的代码适用于对象。你可以在这里找到这样的功能:JavaScript 中的对象比较

在接下来的部分中,我已经放置了示例代码,您可以如何:

  1. 使用localStorage.
  2. 使您的代码适用于原语。
  3. 使您的代码适用于复杂的对象。

在 localStorage 中加载并保存

//Saving array with specific "name" (key for the localStorage)
function saveArray(name, array) {
   localStorage.setItem(name, JSON.stringify(array));
}

//Loads specific array and deserialize it.
function loadArray(name) {
   return JSON.parse(localStorage.getItem(name));
}

对于原语:

对于原语,您可以很容易地实现所需的功能(您的代码对于此类数据是正确的):

//This method adds unique elements, which are not already in the array
Array.prototype.addUnique = function (item) {
   if (this.indexOf(item) < 0) {
      this.push(item);
   }
};

var array = [];
array.addUnique(1);
array.addUnique(2);
array.addUnique(1);
array.addUnique(3);
//The current content of the array is [1,2,3] because of the addUnique functionality
saveArray('myarray', array);

当您重新加载页面时,请使用:

var array = loadArray('myarray'); //[1,2,3]
array.addUnique(6);
saveArray('myarray', array);

现在在你localStorage的价值array将是[1,2,3,6]

对于对象

如果您的数组中有更复杂的数据,例如键值对对象,请使用:

//Code from here:
//https://stackoverflow.com/questions/1068834/object-comparison-in-javascript
Object.prototype.equals = function(x) {
  var p;
  for(p in this) {
      if(typeof(x[p])=='undefined') {return false;}
  }

  for(p in this) {
      if (this[p]) {
          switch(typeof(this[p])) {
              case 'object':
                  if (!this[p].equals(x[p])) { return false; } break;
              case 'function':
                  if (typeof(x[p])=='undefined' ||
                      (p != 'equals' && this[p].toString() != x[p].toString()))
                      return false;
                  break;
              default:
                  if (this[p] != x[p]) { return false; }
          }
      } else {
          if (x[p])
              return false;
      }
  }

  for(p in x) {
      if(typeof(this[p])=='undefined') {return false;}
  }

  return true;
}

Array.prototype.exists = function (item) {
   var exists = false;
   this.forEach(function (e) {
      if (e.equals(item)) {
         exists = true;
         return;
      }
   });
   return exists;
};

Array.prototype.addUniqueObject = function (item) {
    if (!this.exists(item)) {
       this.push(item);
    }
};

var array = [];
array.addUniqueObject({ foo: 'bar' });
array.addUniqueObject({ foo: 'baz' });
array.addUniqueObject({ foo: 'bar' });
array.addUniqueObject({ foo: 'foobar' });
//The current content of the array is [{ foo: 'bar' }, { foo: 'baz' }, { foo: 'foobar' }] because of the addUniqueObject functionality
saveArray('myarray', array);

当您重新加载页面时,您可以使用以下方法获取具有相同内容的数组:

loadArray('myarray');
//[{ foo: 'bar' }, { foo: 'baz' }, { foo: 'foobar' }]

笔记

就像equals添加了方法一样Object.prototype,您创建的每个对象都将具有此方法!每个具有addUnique,addUniqueObject和的数组也是如此equals

如果你不想要这个,你可以简单地重构一些这些方法。

于 2013-02-19T12:37:59.673 回答
2

我在这里错过了什么,localStorage 和 JSON 做了什么来改变我的数组?

它不会改变你的数组(你的旧数组在卸载页面时丢失了)。它创建了一个全新的项目对象。如果您现在创建的项目看起来与您已经拥有的项目完全一样,它们仍然是两个不同的对象,并且通过引用比较它们(就像indexOf那样===)将产生false

所以要么你需要改变你的构造函数,不构建新的,但重用旧的,或者你需要使用一个特殊的比较函数,例如通过它们的 id 告诉对象相等。

于 2013-02-19T12:58:48.433 回答