2012-05-02 11 views
5

Desde que empecé a trabajar con JS, he pensado en la única manera de invocar una función de un número literal es para ponerlo en posición de expresión envolviéndolo con parens, así:¿Cuáles son las reglas para invocar funciones en los literales de números en JS?

1.toString(); 
// SyntaxError: identifier starts immediately after numeric literal 

(1).toString(); 
// "1" 

Hoy en día, se me ocurrió intentar esto:

0.1.toString(); 
// "0.1" 

¿Por qué funciona esto? Un puntero a la especificación oficial sería genial.

Editar ambigüedad fue lo primero que pensé, pero luego decidió que no hay ambigüedad en 1.toString() tampoco. Es más profundo de lo que pensé en un principio, pero todavía creo que estoy en lo cierto. He aquí por qué:

Los nombres de propiedades puede comenzar con dígitos

var obj = { "1" : 1, "2" : 2 }; 

nombres de propiedad que comiencen con los dígitos sólo pueden ser referenciados con corchetes

obj.1; 
// SyntaxError: Unexpected token ILLEGAL 
obj['1']; 
// 1 

también:

1['toString'](); 
// '1' 

Por lo tanto, 1. seguido de cualquier dígito no siempre será una llamada al método o acceso a la propiedad, nunca un número decimal. Del mismo modo, 1. seguido de cualquier dígito siempre será un número decimal, nunca un método de llamada o acceso a la propiedad.

+1

Como nota, puede usar '1..toString()', el primer '.' indica el punto decimal, el segundo indica el uso de la función. – zzzzBov

+1

Relacionado: http://stackoverflow.com/q/2300197 – CMS

+0

Clever, gracias zzzzBov y CMS. – mwcz

Respuesta

5

Una vez que se ha visto en la primera .0.1, a continuación, una posterior . no puede ser parte de la serie.

Todo se basa en la ambigüedad.

edición — la sección 7.8.3 de la especificación insiste explícitamente en esto:

El carácter fuente inmediatamente después de un NumericLiteral no debe ser una IdentifierStart o DecimalDigit.

No estoy seguro exactamente lo que está tratando de prevenir, pero el léxico JavaScript es bastante retorcido, sobre todo gracias a la gramática literal de expresiones regulares y la necesidad de un raro analizador léxico-piratear a lidiar con eso.

+0

No creo que haya ninguna ambigüedad aquí. Actualizando mi pregunta con el razonamiento. Estoy confundido por esa frase de la especificación ... '0.1.toString()' es válida, pero me parece una NumericLiteral seguida de una DecimalDigit. – mwcz

+0

@mwcz Sí, estoy de acuerdo en que no hay una * aparente * ambigüedad, pero puede haber alguna razón oscura para insistir en que el caso se trate como un error. La especificación no entra en ningún detalle real. Y '0.1.toString' es * no * un literal numérico seguido de un dígito decimal: es un literal numérico seguido de un carácter' .', que no es un dígito decimal ni un inicio de identificador. – Pointy

+0

Ah, gracias. Miré '.' y no pude distinguirlo de' .' :) Agregué el razonamiento en contra de la ambigüedad, aunque supongo que habrás llegado de forma independiente. – mwcz

Cuestiones relacionadas