2012-04-10 19 views
10

para repetir las propiedades de un Object en AS3 puede utilizar for(var i:String in object) así:¿Qué sucede cuando uso para (i en objeto) en AS3?

objeto:

var object:Object = { 

    thing: 1, 
    stuff: "hats", 
    another: new Sprite() 

}; 

Loop:

for(var i:String in object) 
{ 
    trace(i + ": " + object[i]); 
} 

Resultado:

 
stuff: hats 
thing: 1 
another: [object Sprite] 

El orden en que se seleccionan las propiedades parece variar y nunca coincide con nada que se me ocurra, como el nombre de la propiedad alfabética, el orden en que se crearon, etc. De hecho, si lo intento unas pocas diferentes tiempos en diferentes lugares, el orden es completamente diferente.

¿Es posible acceder a las propiedades en un orden determinado? ¿Que está sucediendo aquí?

+1

La forma en que pienso de un objeto como se declaró anteriormente, es como una tabla hash como se ve en algunos otros idiomas, donde nunca se puede confiar en el orden debido a cómo se maneja internamente. La idea general se puede encontrar aquí: http://en.wikipedia.org/wiki/Hash_table – ToddBFisher

+0

buena pregunta. aunque no tengo idea de por qué la iteración sobre las propiedades de los objetos es aparentemente aleatoria, recuerdo hilos pasados ​​que discutían problemas similares y la solución fue crear un diccionario que se pasa a una matriz ordenada por las claves o valores del diccionario. También me interesaría saber qué está pasando aquí. – TheDarkIn1978

+1

Creo que @ToddBFisher tiene la idea correcta aquí. En C++ esto sería básicamente un "mapa desordenado", específicamente std :: unordered_map del nuevo estándar C++ 11 implementado en la versión TR1. Consulte http://en.wikipedia.org/wiki/Unordered_associative_containers_(C%2B%2B) y http://www.cplusplus.com/reference/stl/map/ para obtener más detalles sobre el concepto en funcionamiento. –

Respuesta

9

Estoy publicando esto como una respuesta solo para complementar BoltClock's answer con un poco de información adicional mirando directamente el código fuente del reproductor flash. De hecho, podemos ver el código AVM que proporciona específicamente esta funcionalidad y está escrito en C++. Podemos ver el interior ArrayObject.cpp el siguiente código:

// 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); 
    } 
} 

Como se puede ver cuando hay una propiedad legítima (objeto) para volver, se levantó la vista de la clase ScriptObject, específicamente el método nextName(). Si nos fijamos en los métodos dentro 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; 
} 

Podemos ver que, en efecto, que la gente ha señalado aquí que la máquina virtual está utilizando una tabla hash. Sin embargo, en estas funciones se proporciona un índice específico, lo que sugeriría, a primera vista, que debe haber un orden específico.

Si profundizas (no voy a publicar todo el código aquí) hay una gran cantidad de métodos de diferentes clases involucradas en el para/para cada funcionalidad y uno de ellos es el método ScriptObject::nextNameIndex() que básicamente se detiene toda la tabla hash y simplemente comienza a proporcionar índices a los objetos válidos dentro de la tabla e incrementa el índice original proporcionado en el argumento, siempre que el siguiente valor apunte a un objeto válido. Si estoy en lo cierto en mi interpretación, esta sería la causa de su búsqueda aleatoria y no creo que haya ninguna forma de forzar un mapa estandarizado/ordenado en estas operaciones.

Fuentes
Para aquellos de ustedes que quieran obtener el código fuente de la porción de código abierto del reproductor flash, puede agarrarlo de los siguientes depósitos de mercurio (se puede descargar una snapshop en zip como GitHub por lo que no tiene que instalar mercurial):

http://hg.mozilla.org/tamarin-central - Esta es la "estable" o repositorio de "liberación"

http://hg.mozilla.org/tamarin-redux - Esta es la rama de desarrollo. Los cambios más recientes a la AVM se encontrarán aquí. Esto incluye el soporte para Android y tal. Adobe todavía está actualizando y está abriendo fuentes para estas partes del reproductor flash, por lo que es bueno y material oficial.

Mientras estoy en esto, esto también podría ser de interés: http://code.google.com/p/redtamarin/. Es una versión ramificada (y bastante madura) de la AVM y se puede utilizar para escribir actionscript del lado del servidor. Lo bueno y tiene mucha información que da una idea del funcionamiento del AVM, así que pensé en incluirlo también.

+1

Esta es una gran respuesta, gracias. – Marty

+1

No hay problema. Voy a editarlo y publicar las fuentes donde las personas pueden obtener la parte de código abierto del reproductor. –

7

Este comportamiento es documented (énfasis mío):

Los for..in itera bucle a través de las propiedades de un objeto, o los elementos de una matriz. Por ejemplo, se puede utilizar un bucle for..in a repetir las propiedades de un objeto genérico (propiedades de los objetos no se guardan en ningún orden en particular, por lo que las propiedades pueden aparecer en un orden aparentemente aleatorio)

Cómo las propiedades se almacenan y recuperan parece ser un detalle de implementación, que no está cubierto en la documentación. Como ToddBFisher menciona en un comentario, sin embargo, una estructura de datos comúnmente utilizada para implementar matrices asociativas es hash table. Incluso se menciona en this page about associative arrays in AS3, y si inspect the AVM code as shown by Ascension Systems, encontrará exactamente tal implementación. Como se describió, no existe la noción de orden o clasificación en tablas hash típicas.

No creo que haya una forma de acceder a las propiedades en un orden específico a menos que almacene esa orden de alguna manera.

Cuestiones relacionadas