只要项目尚不存在,我就会将其从一个数组移动到另一个数组,然后将其存储在 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.indexOf(item)”就会失败。 queue
的内容与调用 store()/load()
方法之前的内容不同。
以下是我的页面重新加载之前和之后的一些 console.log()
调用,从空的队列
开始。日志已添加到 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
正在做什么来更改我的数组。
我可以看到日志将从存储返回的项目列为“Object”,而原始项目的“类型”(不太确定)为“e”。
如果我使用 typeof
两者的结果都是“object”
最佳答案
indexOf
如果它们是对象,则将通过引用比较值,因此您的代码不适用于复杂对象(即哈希、字典或其他对象)。如果您使用检查对象是否相等的函数,您甚至可以使代码适用于对象。您可以在这里找到这样的功能:Object comparison in JavaScript
在接下来的部分中,我将提供示例代码,您可以:
- 使用
localStorage
加载和保存数组/对象。 - 让您的代码适用于基元。
- 让您的代码适用于复杂的对象。
加载并保存在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
的数组也是如此。
如果您不希望这样,您可以简单地重构一下这些方法。
关于使用 localStorage 后 JavaScript Array.indexOf() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14957580/