Gramática


Tabla de contenidos:

Tener una visión general de la gramática será de gran ayuda para desarrollar código de calidad, organizado y entendible por eso  vamos a utilizar unos diagramas sintácticos, o diagramas de ferrocarril esto nos permitirá comprender fácilmente la representación de forma visual.

Las reglas para la interpretación de estos diagramas son simples:

  • Comenzamos en el borde izquierdo y seguimos cada una de las pistas hasta el borde derecho.
  • A medida que avanzamos, encontraremos literales en óvalos y reglas o descripciones en rectángulos.
  • Es legal realizar cualquier secuencia siguiendo las pistas.
  • No es legal realizar cualquier secuencia que no siga las pistas.
  • Los diagramas de ferrocarril con una barra en cada extremo permiten espacios en blanco para insertarse entre cualquier par de fichas. Diagramas de ferrocarril con dos barras en cada extremo no lo hacen.

La gramática que vamos a ver es mucho más simple que la gramática del lenguaje completo.

Los espacios en blanco

Los espacios en blanco dan la forma a caracteres y comentarios. El espacio en blanco es generalmente insignificante, pero a veces es necesario el uso de un espacio en blanco para separar secuencias de caracteres que de otro modo se combinan en un único token. Por ejemplo, en:

var miVariable = "prueba";

el espacio entre var no se puede quitar, pero los otros espacios pueden ser eliminados.

JavaScript ofrece dos formas de comentarios, comentarios en bloque formados con /* */ y los comentarios de fin de línea comienzan con //

Los comentarios deben ser usados ​​libremente para mejorar la legibilidad de los programas. Ten cuidado de que los comentarios siempre describen con precisión el código. Un comentario obsoleto siempre es peores a que no haya comentario. 

En JavaScript, los pares también pueden ocurrir en literales de expresiones regulares, por lo que los bloques de comentarios no son seguros para comentar bloques de código. Por ejemplo:

var rm_a = /a*/.match(s);

Lo anterior provoca un error de sintaxis. Por lo tanto, se recomienda no utilizar comentarios /* */ y en su lugar utilizar // para comentar. Entonces en los artículos que publiquemos de JavaScript utilizaremos exclusivamente comentarios con // para trabajar con nuestro código.

// Utilizaremos este tipo de comentarios
var miVariable=this;

Nombres

Un nombre es una letra eventualmente seguida de una o más letras, dígitos o guiones bajos. La siguiente es una lista de palabras reservadas del lenguaje JavaScript, entonces no podemos utilizarlas para nuestros nombres:

  • abstract
  • boolean break byte
  • case catch char class const continue
  • debugger default delete do double
  • else enum export extends
  • false final finally float for function
  • goto
  • if implements import in instanceof int interface
  • long
  • native new null
  • package private protected public
  • return
  • short static super switch synchronized
  • this throw throws transient true try typeof
  • var volatile void
  • while with

La mayoría de las palabras reservadas de esta lista no se utilizan en el lenguaje de JavaScript, pero si en otros lenguajes, por eso están clasificadas como reservadas, esta lista puede ampliarse en un futuro tal ves no inmediato, por eso es recomendable estar siempre actualizado con la documentación oficial.

La lista no incluye algunas palabras que deberían haber sido reservados pero no eran, como undefined, NaN, y Infinity. No se permite nombrar a una variable o un parámetro con una palabra reservada. Peor aún, no se permite el uso de una palabra reservada como el nombre de una propiedad de objeto en un objeto literal o después de un punto en un refinamiento.

Los nombres se utilizan para las declaraciones, variables, parámetros, nombres de propiedades, operadores y etiquetas.

Números

JavaScript tiene un único tipo de número. Se representa internamente como punto flotante de 64 bits, el mismo double de Java. A diferencia de los otros lenguajes de programación, no hay ningún tipo de entero por separado, por lo que 1 y 1.0 son el mismo valor. Esta es una comodidad importante porque los problemas de desbordamiento de enteros cortos se evitan completamente, y todo lo que se necesita saber acerca de un número es que se trata de un número. Se evita una gran clase de errores de tipo numérico.

Si un número literal tiene una parte exponencial, entonces el valor del literal se calcula multiplicando la parte antes de e por 10 elevado a la potencia de la parte después de e. Así 100 y 1e2 son el mismo número.

Los números negativos se pueden formar mediante el uso del operador prefijo - .

El valor NaN es un valor numérico que es el resultado de una operación que no puede producir un resultado normal. NaN no es igual a cualquier valor, incluyendo en sí. Puede detectar NaN con la función isNaN (número).

El valor infinito representa todos los valores mayores 1.79769313486231570E 308.

Los números tienen métodos (los veremos más adelante). JavaScript tiene el objeto Math que contiene un conjunto de métodos que actúan sobre los números. Por ejemplo, el método Math.floor(número) se puede utilizar para convertir un número en un número entero.

var miNumero = Math.floor(1.6);
console.log(miNumero);           // retorna 1

El ejercicio anterior retorna uno, ya que redondea hacia abajo el número a su entero más cercano.

Cadenas

Un literal de cadena puede ser envuelto en comillas simples o dobles. Puede contener cero o más caracteres. La barra invertida \ es el carácter de escape. JavaScript fue construido en un momento en que el Unicode era un conjunto de caracteres de 16 bits, por lo que todos los caracteres de JavaScript son de 16 bits de ancho.

JavaScript no tiene un tipo de carácter. Para representar un carácter, haz una cadena con un solo carácter en ella.

Las secuencias de escape permiten insertar caracteres en cadenas que normalmente no están permitidos, tales como barras invertidas, citas, y caracteres de control. La convención \u permite especificar puntos de código de carácter numérico.

Ejemplo:

 "A" === "\u0041"

Las cadenas tienen una propiedad length. Por ejemplo:

var totalCaracteres = "siete".length;
console.log(totalCaracteres);    // Retorna 5

Dos cadenas que contienen exactamente los mismos caracteres y en el mismo orden se consideran la misma cadena. Así:

console.log('g' + 'a' + 't' + 'o' === 'gato');    // Retorna true

Esto da como resultado true.

Las cadenas cuentan con métodos, lo veremos más adelante.

var miCadena = 'gato'.toUpperCase();
console.log(miCadena);    // Retorna GATO

o podemos hacer así:

console.log('gato'.toUpperCase( ) === 'GATO');    // Retorna true

Declaraciones

Una unidad de compilación contiene un conjunto de instrucciones ejecutables. En los navegadores web, cada etiqueta <script> entrega una unidad de compilación que se compila e inmediatamente se ejecuta. A falta de un enlazador JavaScript arroja a todos ellos en un espacio de nombres común de forma global. Luego veremos más información con respecto a esto. Cuando se utiliza dentro de una función, la sentencia var define las variables privadas de la función. 

Las declaraciones switch, while, for, y do nos permiten tener un prefijo de etiqueta opcional break que interactúa con la declaración. 

Las declaraciones tienden a ser ejecutados en orden de arriba a abajo. La secuencia de ejecución puede ser alterada por las sentencias condicionales ( if ó switch ), en las declaraciones de bucles (while, for, y do), en las declaraciones disruptivas (break, return, y throw), y por la invocación de una función.

Un bloque es un conjunto de declaraciones envueltos entre llaves { }. A diferencia de muchos otros idiomas, los bloques de JavaScript no crean un nuevo ámbito, por lo que las variables deben ser definidas en la parte superior de la función, no en los bloques. 

La sentencia if cambia el flujo del programa basado en el valor de la expresión. Entonces el bloque se ejecuta si la expresión es verdadera, de lo contrario, se toma la rama opcional del else.

Éstos son valores ‘Falsy’:

  • false
  • null
  • undefined
  • Una cadena vacia ''
  • El número 0
  • El número NaN

Todos los demás valores son 'truthy', incluyendo true, la cadena 'false', y todos los objetos.

La sentencia switch realiza una derivación de múltiples vías. En él se compara la expresión de igualdad con todos los casos mencionados. La expresión puede producir un número o una cadena. Cuando se encuentra una coincidencia exacta, se ejecutan las sentencias de la cláusula del case. Si no hay ninguna coincidencia, se ejecuta la sentencia default.

Una cláusula case contiene una o más expresiones case. Las expresiones case no necesitan ser constantes. La instrucción que sigue a una cláusula debe ser una declaración disruptiva para prevenir la caída al siguiente case. Puede utilizarse la sentencia break para salir de un switch.

La sentencia while ejecuta un simple bucle. Si la expresión es Falsy, entonces el bucle se romperá. Mientras la expresión sea truthy, se ejecutará el bloque.

La sentencia for es una sentencia de bucle más complicada. Se presenta en dos formas.

La forma convencional es controlada por tres cláusulas opcionales: la inicialización, la condición y el incremento. Primero se realiza la inicialización que típicamente inicializa la variable de bucle. A continuación, se evalúa la condición. Esto comprueba la variable de bucle en sobre un criterio de terminación. Si la condición se omite, se asume una condición de verdad. Si la condición es Falsy, se rompe el bucle. De lo contrario, el bloque es ejecutado. A continuación, el incremento se ejecuta, y entonces el bucle se repite con la condición.

La otra forma (llamada for in) enumera los nombres de propiedad (o claves) de un objeto. En cada iteración, otra serie de nombre de la propiedad del objeto se le asigna a la variable. Por lo general, es necesario someter a prueba a object.hasOwnProperty (variable) para determinar si el nombre de la propiedad es realmente un miembro del objeto o se encontró en cambio en la cadena de prototipos.

for (miVariable in objeto) {
    if (objeto.tieneSusPropiedades(miVariable) {
        ...
    }
}

La sentencia do es como la sentencia while, excepto que la expresión se comprueba después de que el bloque se ejecute antes. Esto significa que el bloque siempre se ejecutará al menos una vez.

La sentencia try ejecuta un bloque y captura las excepciones lanzadas por el bloque. La cláusula catch define una nueva variable que recibirá la excepción del objeto.

La sentencia throw lanza una excepción. Si la sentencia throw está en un bloque try, el control pasa a la cláusula catch. De lo contrario, la invocación de la función es abandonado, y el control pasa a la cláusula catch de try en la función de llamada.

 

La expresión suele ser un objeto literal que contiene una propiedad  nombre y una propiedad mensaje. Los catcher de la excepción pueden utilizar esa información para determinar qué hacer.

La sentencia return provoca un retorno anticipado de una función. También se puede especificar el valor a ser retornado. Si no se especifica una expresión de retorno, entonces el valor de retorno será indefinido.

JavaScript no permite un fin de línea entre el return y la expresión.

La sentencia break provoca la salida desde una sentencia de bucle o de una sentencia switch. Puede opcionalmente tener una etiqueta que provoque una salida de la instrucción etiquetada.

JavaScript no permite un fin de línea entre el break y la etiqueta.

 

La declaración de una expresión puede asignar cualquiera de los valores de una o más variables o miembros, invocar un método, eliminar una propiedad de un objeto. El operador = se utiliza para la asignación. No se debe confundir con el operador de igualdad === . El operador + = puede agregar o concatenar.

 

Expresiones

Las expresiones simples son un valor literal (como una cadena o un número), una variable, un valor built-in (true, false, null, undefined, NaN o Infinity), una expresión invocada precedida por new, una expresión refinada precedida por delete, una expresión envuelta entre paréntesis, una expresión precedida por un operador de prefijo, o una expresión seguida por:

  • Un operador infijo y otra expresión. 
  • El operador ternario ? seguido por otra expresión, entonces por:, y luego por 
  • otra expresión 
  • Una invocación 
  • Un refinamiento

El operador ternario ? toma tres operandos. Si el primer operando es verdadero, produce el valor del segundo operando. Pero si el primer operando es Falso, produce el valor del tercer operando.

Los operadores de la parte superior en la lista de prioridades en la tabla 2-1 tienen mayor precedencia. Se unen los más estrechos. Los operadores en el fondo tienen la prioridad más baja. Se pueden utilizar paréntensis para alterar la prioridad normal, así:

2 + 3 * 5 === 17

(2 + 3) * 5 === 25

. [] ( ) Refinamiento e invocación
delete new typeof + - ! operadores unarios
* / % Multiplicación, división, modulo
+ - Suma / concatenación, resta
>= <= > < desigualdad
=== !== igualdad
&& lógico AND
|| lógico OR
?: Ternario

Los valores producidos por typeof son 'número', 'cadena', 'boolean', 'undefined', 'function' y 'object'. Si el operando es un array o null, el resultado es un "object", lo cual es incorrecto.

Si el operando de ! es verdadero, produce false. De lo contrario, produce true.

El operador + suma o concatena. Si usted lo quiere realizar una operación de suma, asegúrese de que ambos operandos son números.

El operador / puede producir un resultado no entero, incluso si ambos operandos son enteros.

El operador && produce el valor de su primer operando si el primer operando es Falsy. De lo contrario, se produce el valor del segundo operando.

El operador | | produce el valor de su primer operando si el primer operando es truthy. De lo contrario, se produce el valor del segundo operando.

Invocación provoca la ejecución de un valor de la función. El operador de invocación es un par de paréntesis que siguen el valor de la función. Los paréntesis pueden contener argumentos que serán entregados a la función.

Un refinamiento se utiliza para especificar una propiedad o elemento de un objeto o matriz. 

Literales

Los literales de objetos son una notación conveniente para especificar los objetos nuevos. Los nombres de las propiedades se pueden especificar como nombres o como cadenas. Los nombres se tratan como nombres literales, no como nombres de variables, por lo que los nombres de las propiedades del objeto deben ser conocidas en tiempo de compilación. Los valores de las propiedades son expresiones.

Los literales de matriz son una notación conveniente para especificar los nuevos arrays.

Más adelante también veremos expresiones regulares.

Funciones

Una función literal define un valor de la función. Puede tener un nombre opcional que puede utilizarce para llamarse a sí mismo de forma recursiva. Puede especificar una lista de parámetros que actuarán como variables inicializadas por los argumentos de invocación. El cuerpo de la función incluye definiciones y declaraciones variables.

Los tipos simples de JavaScript son números, cadenas, booleanos (true y false), null y undefined. Todos los demás valores son objetos. Los números, cadenas y valores booleanos son objetual en que tienen métodos, pero son inmutables. Los objetos en JavaScript son colecciones mutables con llave. En JavaScript, las matrices son objetos, las funciones son objetos, las expresiones regulares son objetos, y, por supuesto, los objetos son objetos.

Añadir nuevo comentario

CAPTCHA
Esta pregunta es para comprobar si usted es un visitante humano y prevenir envíos de spam automatizado.
5 + 7 =
Resuelva este simple problema matemático y escriba la solución; por ejemplo: Para 1+3, escriba 4.