2009-10-02 22 views
81

Es decir, si uso la hora actual como un índice en la matriz:¿Las matrices de Javascript son dispersas?

array[Date.getTime()] = value; 

será el intérprete instanciar todos los elementos de 0 a ahora? ¿Los diferentes navegadores lo hacen de manera diferente?

Recuerdo que solía haber un error en el kernel AIX, que crearía pseudo-ttys a petición, pero si lo hiciera, digamos, "echo>/dev/pty10000000000" crearía/dev/pty0,/dev/pty1, .... y luego caen muertos. Fue divertido en ferias comerciales, pero no quiero que esto suceda a mis clientes.

+0

¿Por qué no lo prueba y ve si se cuelga? –

+0

@NickLarsen: http://jsbin.com/okuze <- no crash ... ;-) – Shog9

+1

Una posible desventaja de hacer esto es la dificultad de depuración en Firebug. una declaración de registro en la matriz solo mostrará los primeros 1000 elementos en la matriz, que serán "indefinidos". Además, array.length te dirá que tu matriz tiene n elementos, aunque n-1 son solo valores "fantasmas" indefinidos. –

Respuesta

33

El modo exacto en que se implementan las matrices JavaScript difiere de un navegador a otro, pero generalmente recurren a una implementación escasa, probablemente la misma que se utiliza para el acceso a propiedades de objetos regulares, si usar una matriz real sería ineficiente.

Tendrás que pedirle a alguien con más conocimiento sobre implementaciones específicas que responda lo que excactamente desencadena el cambio de denso a disperso, pero tu ejemplo debería ser perfectamente seguro. Si desea obtener una matriz densa, debe llamar al constructor con un argumento de longitud explícito y esperar que realmente obtenga uno.

Consulte this answer para obtener una descripción más detallada de olliej.

+0

No creo que en realidad obtengas una matriz densa si dices algo como 'foo = new Array (10000) '. Sin embargo, se supone que esto funciona: 'foo = Array.apply (null, {length: 10});'. – Taurus

56

Sí, lo son. En realidad, son tablas hash internas, por lo que puede usar no solo números enteros grandes sino también cadenas, flotantes u otros objetos. Todas las claves se convierten a cadenas a través del toString() antes de agregarse al hash. Puede confirmar esto con un poco de código de prueba:

<script> 
    var array = []; 
    array[0] = "zero"; 
    array[new Date().getTime()] = "now"; 
    array[3.14] = "pi"; 

    for (var i in array) { 
     alert("array["+i+"] = " + array[i] + ", typeof("+i+") == " + typeof(i)); 
    } 
</script> 

Muestra:

array[0] = zero, typeof(0) == string 
array[1254503972355] = now, typeof(1254503972355) == string 
array[3.14] = pi, typeof(3.14) == string 

Aviso cómo he utilizado for...in sintaxis, que sólo le da los índices que en realidad están definidos. Si usa el estilo de iteración for (var i = 0; i < array.length; ++i) más común, obviamente tendrá problemas con los índices de matriz no estándar.

+0

¿Las matrices son solo un objeto JS normal que almacena índices/valores en el mecanismo normal de "propiedades"? Eso es lo que parece sugerir el código. Entonces supongo que una matriz JS tiene algunos prototipos adicionales, como guinda del pastel de objetos. – Matt

+5

la mayoría de las implementaciones de JS almacenan propiedades indexadas numéricamente en una matriz real si es posible; eso es magia detrás de escena, sin embargo: desde un punto de vista del lenguaje, las matrices son objetos regulares con una propiedad mágica 'length' – Christoph

+0

También hay magia en la sintaxis' for' in' que oculta cosas como 'length' para que solo itere sobre los índices de matriz y no sobre las propiedades o métodos de una matriz. Un problema común que tienen las personas es agregar cosas a 'Object.prototype' o' Array.prototype' que luego rompe todos los bucles 'for ... in' ya que estas propiedades/métodos añadidos no están ocultos. –

7

Los objetos Javascript son escasos, y los arrays son solo objetos especializados con una propiedad de longitud mantenida automáticamente (que en realidad es uno más grande que el índice más grande, no) y algunos métodos adicionales. Estás seguro de cualquier manera; use una matriz si necesita características adicionales y un objeto contrario.

+3

que es desde el punto de vista del lenguaje; las implementaciones realmente usan matrices reales para almacenar propiedades numéricas densas – Christoph

8

Puede evitar el problema mediante el uso de una sintaxis de JavaScript diseñada para este tipo de cosas. Puede tratarlo como un diccionario, pero la sintaxis "for ... in ..." le permitirá agarrarlos a todos.

var sparse = {}; // not [] 
sparse["whatever"] = "something"; 
1

En general, las matrices de JavaScript son escasos, pero podemos hacerlos tan densa como:

la matriz de repuesto:

var a = new Array(3); 
> a 
[ , , ] 
> a.length 
3 
> a[0] 
undefined 
+0

El formato de esta respuesta parece un poco confuso, lo que hace que sea difícil seguir lo que usted quiere decir. ¿Te importaría revisarlo? – ivanreese

+1

Pero la matriz en su ejemplo no es "escasa". – Taurus

-6

Usted puede utilizar local de HTML5 o sessionStorage.

var date=Date.getTime(),value='1234567890'; 
date=date.toString(); 
localStorage.setItem(date, value); 

* El objeto sessionStorage es igual al objeto localStorage, excepto que almacena los datos para una sola sesión. Los datos se eliminan cuando el usuario cierra la pestaña específica del navegador. Para saber más, visite w3schools.com

+2

Pregunta: "¿Las matrices de Javascript son dispersas?" Respuesta: "Puede usar HTML5 localStorage o sessionStorage". ¡¿¡¿¡¿Um que?!?!?! –

Cuestiones relacionadas