我有一组键/值,例如orange = 123,banana = 4,apple = 567。如何将这些键/值存储在javascript对象中,以便我可以:
似乎对于1.对象文字是合适的,但迭代顺序不能保证,而对于2.一组键/值对(对象文字)将提供迭代顺序但不能查找基于密钥的价值。
@ *感谢所有答案 - 这个问题不是常见问题吗?像jQuery这样的库不包含对这种类型的支持吗?
答案 0 :(得分:7)
如何烹饪自己的列表构造函数?
function List(obj) {
if (this instanceof List) {
var t = this,
keys = [];
/* inititalize: add the properties of [obj] to the list,
and store the keys of [obj] in the private keys array */
for (var l in obj) {
keys.push(l);
t[l] = obj[l];
}
/* public:
add a property to the list
*/
t.add =
function(key, value) {
t[key] = value;
keys.push(key);
return t; /* allows method chaining */
};
/* public:
return raw or sorted list as string, separated by [separator]
Without [sort] the order of properties is the order in which
the properties are added to the list
*/
t.iterate =
function(sort,separator){
separator = separator || '\n';
var ret = [],
lkeys = sort ? keys.slice().sort() : keys;
for (var i=0;i<lkeys.length;i++){
ret.push(lkeys[i]+': '+t[lkeys[i]]);
}
return ret.join(separator);
};
} else if (obj && obj instanceof Object) {
return new List(obj);
} else if (arguments.length === 2) {
var a = {};
a[String(arguments[0])] = arguments[1];
return new List(a);
} else { return true; }
/* the 'if (this instanceof List)' pattern makes
the use of the 'new' operator obsolete. The
constructor also allows to be initialized with
2 parameters => 'List(key,value)'
*/
}
现在您可以将其保留(保留道具的顺序)或排序:
var myList =
List( { orange:123,
banana:4,
apple:567 }
);
myList.add('peach',786);
alert(myList.iterate());
/*=>output:
orange: 123
banana: 4
apple: 567
peach: 786
*/
or: alert(myList.iterate(1));
/*=>output:
apple: 567
banana: 4
orange: 123
peach: 786
*/
答案 1 :(得分:2)
你的两个假设都是正确的。不保证对象文字以任何顺序返回键。
在不旋转自己类型的情况下执行此操作的唯一方法是维护一个有序的键列表:
var obj = {
orange:123,
banana:4,
apple:567
}
var keys = ['orange', 'banana', 'apple'];
for (var i=0; i<keys.length; i++){
value = obj[keys[i]]];
}
丑陋,我知道。
答案 2 :(得分:2)
一个简单的封装:
function Dictionary(p)
{
if(!this.Add)
{
Dictionary.prototype.Add = function(a)
{
if(!a.length) {a = [a];}
for(var i = 0, n=a.length; i<n; i++)
{
for(x in a[i])
{
this[x] = a[i][x];
this.keys.push(x);
}
}
}
}
this.keys = [];
if(typeof(p)!='undefined') {this.Add(p);}
}
var a = new Dictionary({'orange':123, 'banana':4, 'apple':567});
alert(a.keys);//returns [orange,banana,apple]
alert(a.keys[0]);//returns orange
alert(a.orange) //returns 123
a.Add({'mango':88}); //another way to add data
a.Add([{kiwi:16},{grapefruit:79}]) //another way to add data
alert(a.keys);//returns [orange,banana,apple,mango,kiwi,grapefruit]
答案 3 :(得分:0)
你可以用不同的方式做到这一点:
var a = {'orange':123, 'banana':4, 'apple':567};
var b = new Object();
b['orange'] = 123;
b['banana'] = 4;
b['apple'] = 567;
var c = new Object();
c.orange = 123;
c.banana = 4;
c.apple = 567;
语法不同,但内部三个声明是等效的。