Rizando el Rizo

En el último capítulo dí una introducción sumamente rápida al ECMAScript. Introduje funciones, variables, y sentencias. Ahora, voy a explicar cómo hacer cosas útiles con estos bloques básicos, para que podamos empezar a hacer prácticos scripts en nuestros achivos VRML.

Más Sobre las Funciones y Declaraciones

Simplemente como recordatorio; un programa de ECMAScript está hecho a partir de funciones que contienen una sucesión de sentencias. Estas sentencias pueden hacer todas clase de cosas. Pueden declarar las variables, usando la palabra clave var, pueden realizar cálculos, o pueden llamar a otras funciones. Cuando se llama a una función, ésta se ejecuta, se regresa al punto del programa en que se hizo la llamada a esta función, y el programa continúa. Así, si empezamos en la función main,

function main() {
   var a, b;
   a = 3;
   b = cuadrado(a);
   print(b);
}

function cuadrado(x) {
   return x * x;
}

se declaran las variables a y b, y a recibe el valor de 3. Entonces se evalua la función cuadrado(a). Esto significa que se la llama con el valor de a (3), y devuelve a *a (esto es, 9). B recibe este valor, y se imprime.

Bien, por el momento, todo tiene sentido. Mira esto en una asignación, el lado derecho de la expresión se evalúa y se asigna a la variable del lado izquierdo. ¿Va todo bien hasta ahora? Bueno, echémos un ojo a algunos de los tipos de variables básicos que podemos usar en ECMAScript.

Los Tipos de Variables básicos

En ECMAScript, hay varios tipos de variable. Éstos representan los diferentes tipos de datos, como los números, las cadenas de texto, y así sucesivamente. Cada variable que declare pertenecerá a determinado tipo. ECMAScript es diferente de muchos otros lenguajes en eso: no tiene que decirle al intérprete (al navegador que ejecuta su programa) a qué tipo pertenecen sus variables. Del mismo modo, una variable puede cambiar de tipo, como se muestra debajo:

var a;
a = 42;
print(a);
a = "hello";
print(a);

Al principio, la variable a no tiene ningún tipo, dado que no se le asignó ningún valor. Se le da el valor 3, convirtiéndola así en una variable numérica. Sin embargo, después de esto, le damos el valor de "hola", una cadena de texto. Esto es absolutamente legal, y puede llevarte un tiempo acostumbrarse si vienes de programar en lenguajes fuertemente tipificados como Java o C. Los diferentes tipos de variables son:

Undefined. (Indefinido)
Éste es el tipo que una variable tiene antes de que se asigne un valor. Tiene el valor indefinido.
Null. (Nulo)
Éste es un tipo que significa la variable no contiene ningún dato. No es indefinido: está vacío. Tiene sólo un valor, nulo.
Boolean
Obedece a valores TRUE (verdadero) o FALSE (falso), como un SFBool.
String (Cadena de caracteres)
Ésta puede ser cualquier sucesión de carácteres, como un SFString.
Number (Numérica)
Éste es un tipo numérico que puede contener cualquier número en el rango de 253 a -253. La explicación real del rango es un poco compleja. Claro que si sabes lo suficiente como para necesitar buscarlo, seguramente tendrás que hacerlo en una guía más compleja. También existen los valores NaN (Not a Number), +infinity, -infinity y + y -0.
Object (Objeto)
Esto es que una colección de propiedades. De momento lo dejaremos, pero volveremos a ello en cuanto sea necesario para seguir.
Volvamos al ejemplo anterior: en este fragmento de código hay dos literales. Éstos son los valores que realmente están en el programa. El número 42 y la cadena "hola" son los literales (los valores de una cadena de caractéres se encierran siempre entre 'simples' o "dobles" comillas). Éstas no pueden cambiarse, y son físicamente parte del programa, al contrario que las variables, que son temporales y pueden cambiar.

Ahora, seguiremos con expresiones y operadores, y aprenderémos cómo realizar cálculos.

Operadores

ECMAScript, y en la mayoría de lenguajes de programación, hay un juego de funciones llamadas operadores que son funcionamientos básicos que se definen para tipos simples de datos. Los usarás mucho al construir programas, junto con otras funciones comunes. Voy a dar una breve apreciación global de los operadores más importantes, para que tengas una noción de cómo trabajan antes de empezar a ponernos en serio.

Hay varios tipos diferentes de operadores. Hay los operadores de tipo unario que sólo actúan sobre una única variable. Por ejemplo, la señal de negación que convierte un número en negativo.

a = -a;

- es un operador de negación de unario en este caso. Hay operadores binarios que trabajan sobre dos valores, como el operador de suma:

a = a + 3;

Hay también operadores relacionales que trabajan sobre comparaciones entre dos variables. Por ejemplo, el operador 'mayor que' (>).

a = (b < 3);

Si b es menor de tres, a recibirá el valor booleano de TRUE. Los operadores relacionales devuelven siempre valores booleanos. Los operadores de igualdad (==)también son operadores relacionales. El último tipo que vamos cubrir ahora son los operadores lógicos. Éstos son los operadores AND y OR ('y' y 'ó') que trabajan sobre valores booleanos. La tabla de abajo es una lista de todos los operadores simples, y una descripción breve de lo que hacen y cómo usarlos.

Operadores Unarios
 
Operador Descripción
- Devuelve el negativo de un argumento numérico.
! Negación. !TRUE es FALSE y !FALSE es TRUE
++ Incremento (agrega 1) del argumento.
-- Decremento (substrae 1) del argumento.
typeOf Devuelve una cadena que contiene el tipo de variable de un valor

Antes de que cubramos los operadores binarios, veamos una cosilla sobre los operadores de incremento y decremento. Éstos pueden venir antes o después de su argumento, dependiendo de cómo quiere que trabajen.

var a = 3;
var b = a++;

En este caso, al final, b será 3 y a será 4. El valor de a se obtiene evaluando el lado derecho de la sentencia, y se incrementa.

var a = 3;
var b = ++a;

Aquí, b valdrá 4 y a también. El valor de a se incrementa y se asigna inmediatamente a b.

Operadores binarios
 
Operador Descripción
+ Suma
- Substracción
* Multiplicación
/ División
% Modulo (el Resto del Entero)

Los operadores relacionales
 
Operador Descripción
< Menor-que
> Mayor-que
<= Menor o igual
>= Mayor o igual
== Igualdad comparativa
!= Desigualdad comparativa

Los operadores lógicos
 
Operador Descripción
&& Y lógico
|| O lógico

Como vimos, los operadores lógicos devuelven valores booleanas. Bien, hemos cubierto los operadores. ¡Estamos preparados para poder usarlos! Estamos muy cerca de ponernos a escribir scripts VRML.

Condicionales

Hay todavía un par de cosas que necesita saber antes de que empiece a programar scripts. Hay ciertos tipos de sentencias que le permiten elegir opciones en sus programas, y crear comportamientos más complejo. Éstos son losBucles y los condicionales. Cubriremos los condicionales primero.

Una declaración condicional le permite verificar algo en su programa para elegir una opción basada en el resultado. La primera sentencia condicional que miraremos es if. Esto va así:

if (expresión booleana) sentencia;

o

if (expresión booleana) 
{ sentencias }

Ambas son exactamente lo mismo. Un bloque de sentencias (puestas entre llaves) es lo mismo que una sola sentencia sin las llaves. Además, si quiere poner una única sentencia, puede ponerla también entre llaves.

Bueno, volvamos al if. El valor que hay en los paréntesis es una expresión booleana, o una expresión que tras evaluarse devuelve un valor booleano. Si el resultado es true la sentencia (o sentencias) posteriores se ejecutan. Si es false, se omiten. Así que el código siguiente imprimirá "hola" si a es igual al número 3.

if (a==3) print("hola");

Hay otra estructura que podemos usar junto con el if. Ésta es la declaración del else (si no...). Debe seguir a la sentencia if, y se ejecuta si la expresión booleana de los paréntesis es false.

if ((a==3) || (b==4)) print("hola");
else print("adios");

Esto imprimirá "hola" si a vale 3 o si b vale 4, o "adiós" si ninguna de las condiciones se cumple. ¡Simple!

Fale, todo es sencillo hasta ahora. Sin embargo, ahora nos encontramos con el único operador ternario. Éste es el operador condicional. Realmente es solo una manera corta de escribir if... else...

pregunta ? sentencia_si_pregunta_es_cierta : sentencia_si_pregunta_es_falsa;

Puede usarse en lugares dónde ua sentencia if completa podría ser un bloque voluminoso y desarreglado. Por ejemplo, asignar un valor a una variable basandonos en otro:

var b = (a<4) ? 3 : 5;

Si a es menor de 4, b valdrá 3 años, de otro modo valdrá 5.

Los Bucles

ECMAScript tiene dos bucles básicos, el bucle while y el bucle for. Ésto permite realizar una sentencia o conjunto de sentencias hasta que una condición se cumpla. Echemos una primera mirada al bucle while.

while (expresión booleana) sentencia;

Como en el if, puede tener una o varias sentencias, usando las llaves. El bucle while comprueba la expresión booleana antes de ejecutar la sentencia. Si el resultado es true, la sentencia se ejecuta. Entonces, la expresión se evalúa de nuevo y el proceso repite. Así el bucle se ejecuta hasta que la expresión sea false.

var a=0;
while (a<3) {
   a = a + 1;
}

Este bucle se ejecutará mientras a no sea mayor que 3, es decir, se ejecutará tres veces, y después a retornará 3.

El otro tipo de bucle es el for. Esto va así:

for (inicialización; expresión booleana; sentencia de bucle) sentencia/s;

Esto, como puede ver, es un poco más complejo. Hay tres partes en la estructura de control del bucle. La primera parte se ejecuta antes de que comienze el bucle, tan sólo una vez. La segunda parte es como la expresión booleana de la sentencia while. Si es true, las sentencias se ejecutan, de otro modo el bucle finaliza. La tercera parte, la sentencia de bucle, se ejecuta cada vez que el bucle reinicia. Así, mirando un ejemplo...

var a;
for (a=0; a<3; a++) {
   print(a);
}
print("Hecho");

Este código declara una variable a. Entonces, comienza un bucle for . Se asigna el valor 0 a la variable a en la inicialización. Entonces, a se incrementa por la sentencia de bucle. La expresión a<3 se evalua de nuevo. a sigue devolviendo un valor menor de 3, por lo que el cuerpo del bucle se ejecuta de nuevo, mientras se imprime el valor 1. a se incrementa de nuevo, se evalúa de nuevo, y el bucle ejecuta de nuevo, imprimiendo 2. la variable a se incrementa, para devolver el valor 3. Ahora, la evaluación resulta false, dado que a NO es menor de 3, el bucle finaliza, y el programa continúa, imprimiendo "hecho." Así de simple.

Hay solo dos cosas más que cubrir antes de que acabemos el capítulo. Éstas son las sentencias break y continue. Pueden ser útiles si quiere manipular el funcionamiento de un bucles. Una entencia break se efinalizará inmediatamente el bucle y continuará con el programa. Una setencia continue detendrá la ejecución actual del cuerpo del bucle y saltará al comienzo del bucle, saltándose las siguientes sentencias del cuerpo del mismo.

var a=0;
while (a<2) {
   print("hola");
   a++;
   break;
}
print("¡adios!");

Esto imprimirá "hola ¡adiós"!, ya que el bucle se interrumpe al llegar al break y prosigue con el programa.

var a=0;
while (a<2) {
   print("hola ");
   a++;
   continue;
   print("saludos ");
}
print("adios!");

Esto imprimirá "hola hola adiós"!, dado que el bucle se interrumpe a medio camino debido al continue y de esta manera nunca llega a imprimirse "saludos". Puede que de momento estas sentencias no le resulten de utilidad, pero es bueno concerlas para más adelante.

Sacacorchos

Bien, esto también ha sido una buena carga de información, ¡pero ahora está en condiciones de lanzarse a hacer scripts de VRML! Si quieres más información sobre programación ECMAScript, hay mazo de recursos de Javascript allí fuera. Solo recuerda que ECMAScript está fundamentalmente basado en Javascript 1.0, por lo que los perfeccionamientos de las versiones posteriores no tienen por qué funcionar adecuadamente. Puede conseguir una copia gratuita de la especificación oficial de ECMAScript en ECMA . En el próximo capítulo, crearemos nuestro primer script. No hará nada asombroso, pero todo llegará, se lo prometo. ¡Todo a su tiempo!