Llego un poco tarde a la pregunta, pero creo que puedo dar una buena respuesta.
La respuesta aceptada no te dice nada más que lo que en realidad se sabe, y la mención en la propia pregunta: Number(value)
obras como +value
pero no como parseInt(value)
.
La clave es saber que existe una diferencia semántica entre conversión de tipo y parsing.
¿Por qué una cadena de número octal se emite como un número decimal?
Debido a que el Number constructor called as a Function (Number(value)
) y el Unary +
Operator (+value
) detrás de las escenas utilice el funcionamiento interno ToNumber
. El propósito de esos constructos es tipo conversión.
Cuando ToNumber
is applied to the String Type se usa una producción de gramática especial, llamada StringNumericLiteral
.
Esta producción puede contener solamente literales decimales y literales hexadecimal entero:
...
StrNumericLiteral :::
StrDecimalLiteral
HexIntegerLiteral
...
También hay diferencias semánticas entre esta gramática y la gramática de "normal" NumericLiterals
.
A StringNumericLiteral
:
- puede estar precedida y/o seguida por espacios en blanco y/o terminadores de línea.
- Eso es decimal puede tener cualquier número de 0 dígitos iniciales. sin octals!
- Ese decimal puede ir precedido de + o - para indicar su signo.
- Eso está vacío o solo contiene espacio en blanco se convierte en +0.
Ahora voy a ir con las funciones parseInt
y parseFloat
.
El propósito de esas funciones, obviamente, es parsing, que es semánticamente diferente a conversión de tipo, por ejemplo:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseFloat("3.5GB"); // 3.5
// etc..
la pena mencionar que el algoritmo de parseInt
cambió en el quinto ECMAScript Edición Especificación, ya no interpreta la raíz de un número como octal solo por tener un cero inicial:
parseInt("010"); // 10, ECMAScript 5 behavior
parseInt("010"); // 8, ECMAScript 3 behavior
Como puede ver, eso introdujo un incompatibility en el comportamiento entre las implementaciones ES3 y ES5, y como siempre se recomienda utilizar el argumento raíz, para evitar cualquier posible problema.
Ahora la segunda pregunta:
Por qué literales octales se lanzan desde un ECMAScript 5ª edición en modo estricto?
En realidad, este esfuerzo de deshacerse de literales octales viene desde 1999. Las producciones literales octales (OctalIntegerLiteral
y OctalEscapeSequence
) fueron retirados de la gramática de NumericLiteral
s ya que el ECMAScript 3rd Edition specification, que podrían ser incluidos para backwards compatibility (also in ES5) con versiones anteriores del estándar.
De hecho, están incluidos en todas las implementaciones principales, pero técnicamente una implementación compatible con ES3 o ES5 podría optar por no incluirlos, ya que se describen como no normativa.
Ese fue el primer paso, ahora ECMAScript 5 Strict Mode los deshabilita por completo.
¿Pero por qué?
Debido a que fueron considerados como una función propensos de error, y de hecho, en el pasado causaron no intencional o difícil de atrapar insectos - al igual que el mismo problema de octales implícitas de parseInt
-.
Ahora, bajo el modo estricto, un literal octal causará una excepción de SyntaxError
, actualmente solo observable en Firefox 4.0 Betas.
Esta es una gran respuesta y más de lo que esperaba originalmente. Supongo que pasé por alto 'StringNumericLiteral' en la especificación, y ciertamente no sabía que se permitía el espacio en blanco. Esa es solo una de esas cosas, siempre esperé que el espacio en blanco resultara en * NaN *. –
Gracias @Andy, sí, a menudo veo gente sorprendida de que, por ejemplo, 'isNaN (" \ t \ r \ n ")' devuelve 'false';) – CMS