无法将具有用户定义的索引的数组保存到localStorage

时间:2018-10-04 08:36:52

标签: javascript local-storage

我有一个对象数组。该数组包含按升序排列的索引和一些其他用户定义的索引。例如:

var myArray = [];
myArray['userIndex1'] = 'userIndex1';
myArray['userIndex2'] = 'userIndex2';
myArray[0]{
    'name' : 'Name1',
    'id' : '114'
}
myArray[1]{
    'name' : 'Name2',
    'id' : '123'
}

我用来将其设置为localStorage的代码是:

localStorage.setItem('mySavedItem', JSON.stringify(myArray));

我面临的问题是通过以下方式进行检索:

JSON.parse(localStorage.getItem('mySavedItem'));

它只给

myArray[0]{
    'name' : 'Name1',
    'id' : '114'
}
myArray[1]{
    'name' : 'Name2',
    'id' : '123'
}

如您所见,在执行JSON.stringify(myArray);时,未返回用户定义的索引,或者可能没有将它们保存在第一手,所以我尝试将它们保留在单独的索引中。因此,我的最终结构变为:

var myArray = [];
myArray['userIndex']{
    'userIndex1': 'userIndex1';
    'userIndex2': 'userIndex2';
}
myArray[0]{
    'name' : 'Name1',
    'id' : '114'
}
myArray[1]{
    'name' : 'Name2',
    'id' : '123'
}

尽管结果仍然相同。它仅保存/检索索引为0和1的数据。结果中不存在用户定义的索引。

我可以通过使所有索引仅按串行顺序来解决它。意味着如果我将myArray['userIndex']作为myArray['2']附加元素,则它可以检索/保存所有数据,但是我无法理解其原因。谁能解释?

2 个答案:

答案 0 :(得分:1)

发生这种情况的原因是由于JSON.stringify方法是defined to work in the official EcmaScript 5.1 specification

  

数组的表示仅包括零之间的元素   和array.length – 1(含)在内。命名属性不包括在   字符串化。数组被字符串化为左方括号,用逗号分隔的元素和右方括号。

这意味着您添加到通过Array.isArray(arr)测试的对象的任何自定义道具将成为序列化的一部分。因此,您可以像完成操作一样向对象添加恰好合适的属性,但是一旦使用JSON.stringify()进行序列化,它们就会丢失。

您可以通过在数组对象上使用自定义toJSON方法来覆盖如何转换数组(和任何对象),但是您可能不想这样做,因为JSON.parse()不会知道如何使自定义对象表示再次成为数组。示例:

a = [1,2,3]
a.toJSON = function(){ return "custom repr"; }
JSON.stringify(a) // "\"custom repr\"" 

如果您实际上希望自定义索引在序列化/反序列化后仍然存在,则需要另一种表示形式来保留它们。在您的情况下,您可以使用一个普通对象,但是当然,您将丢失所有数组操作(例如pushpop等)。

我建议您要么将索引存储在单独的对象上,要么使用其他答案建议的复合结构:

myObj = {
   array: [],
   myIndex1: ...,
   myIndex2: ...
}

答案 1 :(得分:0)

您试图实现的目标是可能的,但是您需要编写其他代码以对数据进行字符串化和解析。我会使用对象而不是数组。 “用户定义的索引”是对象的常规属性,原始数组存储为对象的数组属性。

var myObj = {
  myArray: []
};
myObj['userIndex1'] = 'userIndex1';
myObj['userIndex2'] = 'userIndex2';
myObj.myArray.push({
   'name' : 'Name1',
   'id' : '114'
});
...
localStorage.setItem('mySavedItem', JSON.stringify(myObj));