我有一个对象数组。该数组包含按升序排列的索引和一些其他用户定义的索引。例如:
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']
附加元素,则它可以检索/保存所有数据,但是我无法理解其原因。谁能解释?
答案 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\""
如果您实际上希望自定义索引在序列化/反序列化后仍然存在,则需要另一种表示形式来保留它们。在您的情况下,您可以使用一个普通对象,但是当然,您将丢失所有数组操作(例如push
,pop
等)。
我建议您要么将索引存储在单独的对象上,要么使用其他答案建议的复合结构:
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));