2008-08-26 15 views
26

Código:Javascript navegador Peculiaridades - Array.length

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <title>Unusual Array Lengths!</title> 

    <script type="text/javascript"> 
     var arrayList = new Array(); 
     arrayList = [1, 2, 3, 4, 5, ]; 
     alert(arrayList.length); 
    </script> 

</head> 
<body> 
</body> 
</html> 

Aviso de la coma extra en la declaración de matriz. El código anterior da diferentes salidas para varios navegadores:

Safari: 5

Firefox: 5

IE: 6

El coma adicional en la matriz está siendo ignorada por Safari y FF mientras IE lo trata como otro objeto en la matriz.

En alguna búsqueda, he encontrado opiniones encontradas sobre qué respuesta es la correcta. La mayoría de las personas dice que IE es correcto, pero Safari también está haciendo lo mismo que Firefox. No he probado esto en otros navegadores como Opera, pero asumo que hay discrepancias.

Mis preguntas:

i. ¿Cuál de estos es el correcto?

Editar: Por consenso general (y las pautas de ECMAScript) suponemos que IE nuevamente tiene la culpa.

ii. ¿Hay alguna otra carencia del navegador Javascript de la que deba tener cuidado?

Editar: Sí, hay un montón de peculiaridades de Javascript. www.quirksmode.org es un buen recurso para el mismo.

iii. ¿Cómo evito errores como estos?

Editar: Utilice JSLint para confirmar su javascript. O bien, use algunos externos libraries. O bien, sanitize su código.

Gracias a DamienB, JasonBunting, John y Konrad Rudolph por sus entradas.

+2

¡¡¡Gracias, gracias, gracias!!! ¡Una coma extra estúpida estaba causando que IE8 se comportara de manera diferente a FireFox y me estaba conduciendo por la pared tratando de resolverlo! – Tom

+0

Gracias por hacer esta pregunta, me ayudó a resolver un problema que estaba teniendo con IE no manejando una matriz como se esperaba. :) –

+1

Gracias por esto. Obtuve un error de JavaScript de IE8 cuando revisé el .length de un elemento de matriz. Y la causa fue una coma extra en la declaración de matriz. – jamesnotjim

Respuesta

9

Me parece que el comportamiento de Firefox es correcto. ¿Cuál es el valor del sexto valor en IE (lo siento, no lo tengo a mano para probar). Dado que no se proporciona ningún valor real, me imagino que lo está llenando con algo como 'nulo', que ciertamente no parece ser lo que pretendía que ocurriera cuando creó la matriz.

Al final del día, en realidad no importa cuál es "correcto" ya que la realidad es que o bien está apuntando a un solo navegador, en cuyo caso puede ignorar lo que hacen los demás, o usted dirigido a múltiples navegadores, en cuyo caso su código debe funcionar en todos ellos. En este caso, la solución obvia es no incluir nunca la coma colgante en un inicializador de matriz.

Si tiene problemas para evitarlo (por ejemplo, por algún motivo ha desarrollado un hábito (malo, imho) de incluirlo) y otros problemas como este, entonces algo como JSLint podría ayudar.

3

"3" para esos casos, por lo general poner en mis guiones

if(!arrayList[arrayList.length -1]) arrayList.pop(); 

Se podría hacer una función de utilidad fuera de eso.

+2

Entonces, si el último elemento es 0 o "¿obtiene el cuchillo? – mplungjan

+0

Sí :-) Por supuesto, ese caso nunca ocurre en mis scripts :-) –

+3

if (typeof arrayList [arrayList.length-1] === "undefined") arrayList.pop(); – Tracker1

7

Estaba intrigado, así que lo busqué en la definición de ECMAScript 262 ed. 3 que es la base de JavaScript 1.8. La definición relevante se encuentra en la sección 11.1.4 y lamentablemente no es muy clara. La sección establece explícitamente que las elisiones (= omisiones) al principio o en el medio no definen un elemento , pero sí contribuyen a la longitud total.

de: No hay declaraciones explícitas sobre comas redundantes al final de la inicialización, pero por omisión, llego a la conclusión de que la declaración anterior implica que no lo hacen contribuyen a la longitud total así que la conclusión de que MSIE está mal.

El párrafo pertinente dice lo siguiente:

elementos de la matriz pueden ser elided al principio, medio o al final de la lista de elementos. Siempre que una coma en la lista de elementos no esté precedida por una expresión de asignación (es decir, una coma al principio o después de otra coma), el elemento de matriz faltante contribuye a la longitud de la matriz y aumenta el índice de los elementos subsiguientes. Los elementos de matriz elided no están definidos.

+0

Konrad: "La definición relevante se encuentra en la sección 11.1.4 y desafortunadamente no es muy clara". Me parece bastante claro: "Siempre que una coma en la lista de elementos no sea _preceded_ por una Expresión de Asignación [...]". Solo cuando se haya omitido una expresión que precede a una coma, contará como elemento ([, foo] => 2 elementos). No se menciona la expresión faltante después de una coma ([foo,] => 1 elemento). IE tiene la culpa. – Zuu

+0

Acepto que NO está claro. De la definición de producción ArrayLiteral: [ElementList, Elisionopt]: ... Let pad es el resultado de evaluar Elision; si no está presente, use el valor numérico cero. ... Llame al método interno [[Put]] de matriz con argumentos "longitud", ToUint32 (pad + len) y falso. ... – Chris

+0

... Para mí, esta definición dice establecer la longitud a la longitud del ellision (pad) más la longitud de la lista de elementos precedente. Si no es así como se supone que debo leerlo, alguien por favor ilumíname. – Chris

0

@John: El valor de arrayList [5] es 'indefinido'.

Sí, nunca debería haber una coma que cuelgue en las declaraciones. En realidad, estaba revisando el largo código javascript de otra persona que de alguna manera no funcionaba correctamente en diferentes navegadores. ¡Resultó que la coma que colgaba era la culpable que accidentalmente se ha escrito! :)

2

En primer lugar, Konrad es justo citar la especificación, ya que eso es lo que define el idioma y responde a su primera pregunta.

para responder a sus otras preguntas:

¿Hay otros tales navegador con Javascript peculiaridades que yo debería tener cuidado de?

¡Demasiadas para enumerarlas aquí! Pruebe the QuirksMode website para obtener un buen lugar para encontrar casi todo lo que se conoce.

¿Cómo puedo evitar errores como estos?

La mejor manera es utilizar a library que abstrae estos problemas de distancia para usted para que pueda ponerse a preocuparse por la lógica de la aplicación. Aunque es un poco esotérico, prefiero y recomiendo MochiKit.

1

¿Cuál de estos es el correcto?

Opera también devuelve 5. Eso significa que IE es superado en número y la mayoría gobierna hasta donde se puede esperar.

1

Ecma 262 edition 5.1 sección 11.1.4 inicializador de matriz indica que una coma al final si la matriz no contribuye a la longitud si la matriz. "Si un elemento se elide en el final de la matriz que no contribuye a la longitud de la matriz"

Eso significa [ "x",] es perfectamente legal javascript y deben devolver una matriz de longitud 1

+0

No hay ambigüedad al respecto, es bastante claro en la especificación, que establece explícitamente que 'si un elemento se elimina' [es decir, se omite] 'al final de la matriz, no contribuye a la longitud de la matriz' - no podría ser más claro –

Cuestiones relacionadas