for - matriz javascript
¿Las matrices de JavaScript se implementan realmente como matrices? (2)
La diferencia entre una Array
javascript y un Object
no es muy grande. De hecho, parece que Array
agrega principalmente el campo de length
, por lo que puede usar Array
sy Object
s como arrays numéricos:
var ar = new Array();
ar[0] = "foo";
ar["bar"] = "foo";
var ob = new Object();
ob[0] = "foo";
ob["bar"] = "foo";
assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.
Entonces, mi pregunta es, en los motores populares de javascript (V8, JavaScriptCore, SpiderMonkey, etc.), ¿cómo se maneja esto? Obviamente, ¡no queremos que nuestros arreglos se almacenen realmente como mapas hash con valores clave! ¿Cómo podemos estar razonablemente seguros de que nuestros datos se almacenan como una matriz real?
Por lo que puedo ver, hay algunos enfoques que los motores podrían tomar:
-
Array
se implementa exactamente de la misma forma que elObject
, como una matriz asociativa con claves de cadena. -
Array
es un caso especial, con una matriz tipostd::vector
respalda las teclas numéricas y cierta heurística de densidad para evitar el uso de memoria demente si lo hacear[100000000] = 0;
-
Array
es lo mismo que elObject
, y todos los objetos obtienen una heurística para ver si usar una matriz tendría más sentido. - Algo increíblemente complicado que no he pensado.
Realmente, esto sería más simple si hubiera un tipo de matriz adecuado (toses matrices de tipo WebGL, tos ).
En SpiderMonkey, las matrices se implementan básicamente como matrices C de jsvals. Estos se conocen como "matrices densas". Sin embargo, si comienzas a hacer cosas que no son de una matriz, como tratarlos como objetos, su implementación cambia a algo que se parece mucho a los objetos.
Moraleja de la historia: cuando quieras una matriz, usa una matriz. Cuando quieras un objeto, usa un objeto.
Oh, un jsval es una especie de tipo variadic que puede representar cualquier valor de JavaScript posible en un tipo C de 64 bits.
En V8 y Carakan (y probablemente Chakra), todos los objetos (no host) (tanto los que son arreglos como los que no lo son) con propiedades cuyos nombres son índices de arreglos (definidos en ES5) se almacenan como arreglos densos (una matriz C que contiene algún envoltorio de valor) o una matriz dispersa (que se implementa como un árbol de búsqueda binario).
La representación de objetos unificada se muestra en el sentido de que afecta el orden de enumeración: con un objeto, SpiderMonkey y SquirrelFish dan todas las propiedades en orden de inserción; y con una matriz, en general (¡hay casos especiales en SM al menos!) los índices de matriz primero y luego todas las demás propiedades en orden de inserción. V8, Carakan y Chakra siempre dan índices de matriz primero y luego todas las demás propiedades en orden de inserción, independientemente del tipo de objeto.