Elementos
2. Elementos del Lenguaje:
A. Los datos
Anteriormente has hecho una primera aproximación a los elementos básicos con que vas a enfrentarte al programar. Es el momento de ahondar algo mas en estos elementos y comenzaremos por los más elementales: los datos. JavaScript maneja cuatro tipos de datos: numéricos, de cadena, booleanos y punteros. Los datos numéricos sirven para manejar cualquier número real, como 12, 56.5, -9.
Los datos de cadena son los usados para cadenas alfanuméricas, o sea, para representar palabras, así los siguientes son datos de cadena: 'prueba' , 'La clave es 4r5t'. Observa que estos datos están encerados entre comillas (dobles o simples, se permiten ambas opciones), es la forma de decirle a JavaScript que está ante una cadena de caracteres y no ante un nombre o descriptor de algún elemento del programa. Es decir '41' (o "41") es un dato de cadena mientras que 41 es el número cuarenta y uno. ¿Y que ocurre si quiero que la cadena tenga comillas?, por ejemplo queremos escribir la siguiente frase Juan alias 'Maqui' es el jefe, en JavaScript esto es una cadena y debe encerrarse entre comillas 'Juan alias 'Maqui' es el jefe', la interpretación de esta cadena daría un error como puedes comprobar si escribes en la ventana de scripts la siguiente instrucción:
logger.warn('Juan alias 'Maqui' es el jefe'); // Error
¿Por qué? Pues por que ahí hay dos cadenas y un nombre en medio: 'Juan alias', Maqui y 'es el jefe'. JavaScript intentará encontrar una variable con el nombre Maqui. Para poder hacer esto correctamente se usa el carácter de escape: \, lo que sigue a esta barra invertida es un carácter especial que debe interpretarse como un carácter normal, prueba ahora esto:
logger.warn('Juan alias \'Maqui\' es el jefe');
Alternativamente, podemos combinar comillas simples y dobles para conseguir el mismo resultado:
logger.warn("Juan alias 'Maqui' es el jefe");
Ahora ya funciona perfectamente. Existen mas caracteres especiales como tabulaciones, cambios de línea de escritura, borrado izquierda, la propia barra invertida. Puedes probarlos con la técnica del logger:
logger.warn('Esto usa una \t tabulación');
logger.warn('Esto usa un \n cambio de línea');
logger.warn('Esto usa un \r retorno de carro');
logger.warn('Esto es la barra invertida \\');
Estos datos son bastante habituales incluso en la vida cotidiana, pero existen mas tipos de datos como seguro sabes. Por ejemplo si preguntas a alguien ¿son las cinco en punto? Sólo hay dos posibles respuestas: SI o NO. Este tipo de datos no es ni numérico ni de cadena, es booleano. En los lenguajes de programación en lugar de sí o no se emplean los valores true o false. Estos datos son los que utilizaras cuando en los programas se tengan que tomar decisiones, o sea, comprobar algo y actuar en consecuencia: si una variable de incendio es true desactivar los ascensores, por ejemplo.
Existe un último tipo de datos que también se emplea a menudo en los scripts para la captura de eventos, son direcciones de memoria, o punteros , usadas para asignar funciones. Si en una variable se guarda el nombre de una función esa variable se convierte en otro nombre para esa función.
B. Las variables.
Ya dijimos que los datos, los valores numéricos no siempre pueden utilizarse de manera directa, sino que habitualmente se almacenan en una posición de memoria con nombre, esto es lo que llamamos una variable. En otros lenguajes de programación existen diferentes tipos de variables en función del tipo de datos que pueden guardar: variables para cadenas, para números enteros, para números reales, etc. JavaScript es muy permisivo en este aspecto de manera que una variable puede guardar cualquier tipo de dato y además pueden crearse en cualquier parte del programa. Esto último es cómodo pero peligroso pues puede llevar a programas difíciles de depurar y de modificar, es conveniente llevar un cierto control sobre las variables que vas usando en cada función y declararlas al principio de la misma.
Hemos dicho que las variables tienen nombres, ¿cómo son estos nombres? Vale cualquier combinación de letras y dígitos, mas el guión bajo, siempre que el primer carácter no sea un número y por supuesto que no coincida con una palabra reservada del lenguaje, es decir, palabras con un significado especial para el intérprete como close, open, write... Es aconsejable usar nombres autoexplicativos, es una forma de documentar tus programas. Por ejemplo una variable para guardar una dirección de memoria modbus de un dispositivo puede llamarse direc_modbus. Un último detalle JavaScript diferencia entre mayúsuclas y minúsculas, así Edad y edad serían dos variables distintas.
Otro aspecto a tener en cuenta a la hora de usar las variables es su ámbito , es decir, qué funciones tienen acceso a ellas. Si se crea una variable dentro de una función sólo será conocida dentro de esa función, se trata de variables locales. Si se necesita que varias funciones tengan acceso a una determinada variable ésta debe crearse como variable global , esto se hace con la ayuda de la función globalData Ver sección Ejemplos completos
function estadoLuzDespacho() {
let estado_luz;
estado_luz = devices.read('Despacho', 'Luz');
return estado_luz;
}
En este ejemplo la variable estado_luz es local a la función estadoLuzDespacho(). Observa que las variables están creadas con la palabra clave let. Otro detalle a tener en cuenta es que al mismo tiempo que creamos la variable podemos darle un valor, si no lo hacemos la variable contendrá el valor null.
C. Los Objetos
Javascript posee algunos objetos predefinidos u objetos intrínsecos como son: Array , Boolean , Date , Function , Global , Math , Numbe r, Object , RegExp , y String. Además el programador puede crear objetos nuevos, con sus propios métodos y propiedades, adaptados a las necesidades concretas de su aplicación.
Crear un objeto nuevo es tan simple como definir cuales serán sus propiedades y sus métodos, teniendo en cuenta que cualquier objeto que definamos ya posee heredados los métodos y propiedades del objeto predefinido object. En el ejemplo siguiente creamos un objeto sonda que aclarará la forma de crear objetos propios:
function sonda (temperatura, humedad, bateria) {
this.temperatura = temperatura;
this.humedad = humedad;
this.bateria = bateria;
this.length = 3;
}
let miSonda = new sonda(25, 96, 100);
let nuevaSonda = new sonda(20, 99, 75);
Este objeto se crea con el operador new pasándole como argumentos las propiedades declaradas para este objeto: temperatura , humedad , bateria. La palabra clave this se usa para referirnos al propio objeto que estamos definiendo. Aún mas podemos crear propiedades nuevas sólo para la variable miSonda , pero estas propiedades no afectarán al objeto sonda en sí. Por ejemplo:
miSonda.otra = 'Objeto definido por mi';
logger.warn(miSonda.otra);
da como resultado Objeto definido por mi , pero si ahora escribiéramos:
logger.warn(nuevaSonda.otra);
obtendríamos undefined pues otra solo es una propiedad de la variable miSonda no del objeto nuevasonda. Para ampliar un objeto usamos la propiedad prototype:
sonda.prototype.otro = 'Objeto definido por mi';
logger.warn(nuevaSonda.otro);
logger.warn(miSonda.otra);
Ahora hemos añadido una propiedad al objeto sonda y esta propiedad se transmite a las variables de tipo sonda (mas correctamente instancias de sonda ), por tanto en ambos casos obtendríamos la frase Objeto definido por mí , que es el valor dado a la nueva propiedad.
D. Los Arrays
A pesar de su extraño nombre los arrays no son más que estructuras para almacenar listas de valores. A diferencia de otros lenguajes, en Javascript los arrays no son un tipo de variable sino que fueron implementados por Netscape como un objeto, lo cual les da una potencia enorme. Pero empecemos por abajo. Un array puede verse como una lista con nombre donde podemos anotar cosas, cada anotación se identifica por su número de orden en el array (la lista), su índice, y el número total de espacios para anotar cosas en el array es su longitud. Si en un array tenemos anotados 5 números, el primero de todos será el de índice 0 y el último tendrá como índice el 4, siendo 5 la longitud del array. Simple ¿verdad?, veamos como se crea un array y como se asignan valores en unos ejemplos muy sencillos:
semana = new Array(7);
miLista = new Array(1,5,9);
nombres= new Array('Juan', 'Luis', 'María');
vacio = new Array();
interesante = new Array(4);
El array semana se ha creado con longitud 7, o sea, permite 7 elementos. El array miLista se ha creado con longitud 3 y se ha dado valor a cada elemento al igual que el array nombres. Por último el array vacio se ha creado sin longitud.
semana[0] = 'Lunes';
semana[1] = 'Martes';
semana[2] = 'Miércoles';
semana[3] = 'Jueves' ;
semana[4] = 'Viernes';
semana[5] = 'Sábado';
semana[6] = 'Domingo' ;
vacio[5] = 'ultimo';
interesante['Jose'] = 10;
interesante['Pilar'] = 5;
interesante['Antonio'] = 8;
En este último segmento de código hemos rellenado los arrays: semana se ha rellenado con los nombres de los días de la semana. Observa el array vacio , hemos dado valor al elemento 5, a partir de ahora este array tiene longitud 6 con los cinco primeros elementos con valor null y el sexto (vacio[5]) con valor ' último '. Por último el array llamado interesante , y lo es: los índices no tienen porque ser numéricos.
Cada elemento de un array puede ser un valor de cualquier tipo: números, cadenas ... u otro array, en este último caso tendremos arrays multidimensionales, o sea, donde cada elemento tiene varios índices o coordenadas para localizarlos. ¿Un lio? vemos el caso mas simple, un array bidimensional sería un array donde cada elemento es a su vez otro array con lo que cada elemento tendrá dos índices uno para el primer array y otro para el segundo. El array bidimensional podmeos imaginarlo como una tabla ordenada en filas y columnas, cada elemento del array es una celda de esa tabla. Un ejemplo para una tabla de 3 filas y 2 columnas:
function matBidim() {
let tabla = new Array(3);
tabla[0] = new Array(2);
tabla[0][0] = 10;
tabla[0][1] = 5;
tabla[1] = new Array(2);
tabla[1][0] = 7;
tabla[1][1] = 8;
tabla[2] = new Array(2);
tabla[2][0] = 9;
tabla[2][1] = 3;
logger.warn(tabla[1][1]); /*Visializaría en el log el número 8*/
}
Como ves la cosa es sencilla: el array tabla tiene tres elementos y cada uno de ellos es a su vez otro array de dos elementos.
E. Las Funciones
Las funciones como decíamos en la introducción, no son mas que bloques de instrucciones de programa con nombre y que pueden ejecutarse sin mas que llamarlas desde alguna parte de otra función, bien sea directamente o mediante eventos.
Habitualmente una función se crea para ejecutar una acción muy concreta. Javascript posee una serie de funciones predefinidas o funciones globales pero el programador puede crear las suyas propias. Para crear una función, tan sólo es necesario indicárselo al intérprete mediante la plabra clave function seguida del nombre que deseemos darle a la función y, encerrados entre paréntesis, las variables que simbolizan los valores con los que deba trabajar la función, los argumentos. Los paréntesis deben escribirse aunque no haya argumentos. Para los nombres de funciones seguimos las mismas reglas que para las variables: carateres, dígitos y guión bajo, debiendo comenzar por un carácter o el guión bajo.
Como es natural es recomendable dar a las funciones un nombre representativo de la operación que realize. Por supuesto no debemos darle un nombre que ya exista en JavaScript. A continuación encerradas entre llaves escribimos las sentencias u órdenes en JavaScript. Opcionalmente la función puede finalizar con la palabra clave return seguida de un valor, este valor será el que devuelva la función al programa que la llame. Por ejemplo:
function sumar(a, b) {
let suma;
suma = a + b;
return suma;
}
Mediante este ejemplo creamos la función llamada sumar , que utiliza dos argumentos y lo que hace es sumar estos argumentos. Por último devuelve el resultado de la operación, mediante la palabra clave return seguida del valor que debe devolver. Ahora en el siguiente código de programa usamos la función recién definida:
let operacion;
operacion = sumar(4, 5);
logger.warn(operacion);
En este código llamamos a la función con los argumentos 4 y 5 y almacenamos el resultado en la variable operacion. Hasta aquí el comportamiento de las funciones JavaScript es similar a cualquier otro lenguaje, pero en JavaScript las funciones también son objetos. Veamos el siguiente ejemplo:
let multip = new Function('x', 'y', 'return x * y')
logger.warn(multip(8, 9));
Interesante, ahora multip no es una variable cualquiera sino una instancia del objeto Function y puede usarse como la propia función. Esta característica permite asignar directamente funciones a los eventos y así simplificar su programación.