要在AS3中迭代Object
的属性,您可以使用for(var i:String in object)
,如下所示:
对象
var object:Object = {
thing: 1,
stuff: "hats",
another: new Sprite()
};
循环:
for(var i:String in object)
{
trace(i + ": " + object[i]);
}
结果:
stuff: hats thing: 1 another: [object Sprite]
然而,选择属性的顺序似乎有所不同,并且永远不会匹配我能想到的任何内容,例如字母属性名称,创建它们的顺序等等。事实上,如果我尝试几次不同的时间在不同的地方,顺序完全不同。
是否可以按给定顺序访问属性?这里发生了什么?
答案 0 :(得分:9)
通过直接查看Flash播放器源代码,我发布这个作为答案只是为了赞美BoltClock's answer并提供一些额外的见解。我们实际上可以看到专门提供此功能的AVM代码,它是用C ++编写的。我们可以在ArrayObject.cpp里面看到以下代码:
// Iterator support - for in, for each
Atom ArrayObject::nextName(int index)
{
AvmAssert(index > 0);
int denseLength = (int)getDenseLength();
if (index <= denseLength)
{
AvmCore *core = this->core();
return core->intToAtom(index-1);
}
else
{
return ScriptObject::nextName (index - denseLength);
}
}
正如您所看到的,当有合法属性(对象)返回时,它会从ScriptObject
类中查找,特别是nextName()
方法。如果我们在ScriptObject.cpp中查看这些方法:
Atom ScriptObject::nextName(int index)
{
AvmAssert(traits()->needsHashtable());
AvmAssert(index > 0);
InlineHashtable *ht = getTable();
if (uint32_t(index)-1 >= ht->getCapacity()/2)
return nullStringAtom;
const Atom* atoms = ht->getAtoms();
Atom m = ht->removeDontEnumMask(atoms[(index-1)<<1]);
if (AvmCore::isNullOrUndefined(m))
return nullStringAtom;
return m;
}
我们可以看到,确实,正如人们在此指出的那样,VM正在使用哈希表。然而,在这些功能中,提供了一个特定的索引,乍一看,这表明必须有特定的排序。
如果你深入挖掘(我不会在这里发布所有代码),每个功能中for / for中涉及的不同类都有一大堆方法,其中一个是方法ScriptObject::nextNameIndex()
基本上拉起整个哈希表,只是开始为表中的有效对象提供索引,并递增参数中提供的原始索引,只要下一个值指向有效对象即可。如果我的解释是正确的,那么这就是你随机查找背后的原因,我不相信这里有任何方法可以在这些操作中强制使用标准化/有序地图。
<强>来源强>
对于那些可能想要获取flash播放器的开源部分的源代码的人,你可以从以下的mercurial存储库中获取它(你可以像github一样下载一个zipstore的snapshop,这样你就不必安装mercurial ):
http://hg.mozilla.org/tamarin-central - 这是“稳定”或“发布”存储库
http://hg.mozilla.org/tamarin-redux - 这是开发分支。 AVM的最新更改将在此处找到。这包括对Android等的支持。 Adobe仍在更新并开放采购这些Flash播放器的部分,因此它是当前和官方的好东西。
虽然我很喜欢,但也可能会感兴趣:http://code.google.com/p/redtamarin/。它是AVM的分支(并且相当成熟)版本,可用于编写服务器端动作脚本。整洁的东西,有大量的信息,可以深入了解AVM的工作情况,所以我想我也会把它包括在内。
答案 1 :(得分:7)
此行为是documented(强调我的):
for..in
循环遍历对象的属性或数组的元素。例如,您可以使用for..in
循环来遍历泛型对象的属性(对象属性不以任何特定顺序保留,因此属性可能以看似随机的顺序出现)
如何存储和检索属性似乎是一个实现细节,文档中没有介绍。正如ToddBFisher在评论中提到的那样,通常用于实现关联数组的数据结构是hash table。它甚至在this page about associative arrays in AS3中提到过,如果你inspect the AVM code as shown by Ascension Systems,你会发现这样的实现。如上所述,在典型的哈希表中没有顺序或排序的概念。
我不相信有一种方法可以按特定顺序访问属性,除非您以某种方式存储该订单。