JavaScript, EcmaScript, novedades y recomendaciones del lenguaje
El lenguaje para scripting en
Nota: Aunque el lenguaje es estándar, algunos objetos globales, como "console" no son accesibles desde los scripts.
Algunas nociones sobre las últimas versiones de ES
El motor de scripting de
Funciones flecha o arrow functions
En
Podría a su vez clasificarse las arrow functions en dos clases, a continuación ejemplos de equivalencia en notación tradicional y con flecha.
- De resultado inmediato, que solo ejecutan una sentencia y devuelven ese mismo valor. No usan llaves.
// Función en sintaxis tradicional
function suma(a, b) {
return a + b;
}
// Sintaxis arrow function abreviada, asignando a variable
const suma = (a, b) => a + b;
// Sintaxis arrow function abreviada, usada como parámetro
funcionQueUsaSuma((a,b) => a + b);
- En un sentido más tradicional, incluyendo varias líneas y sentencias. Se han de incluír llaves para delimitar su cuerpo.
// Función en sintaxis tradicional
function activarClima() {
const tExterior = devices.read('SONDAS', 'EXTERIOR');
if(tExterior > 19) {
devices.write('CLIMA', 'ONOFF', true);
} else {
logger.debug('El clima no necesita encenderse');
}
return devices.read('CLIMA', 'ONOFF');
}
// Sintaxis arrow function
const activarClima = () => {
const tExterior = devices.read('SONDAS', 'EXTERIOR');
if(tExterior > 19) {
devices.write('CLIMA', 'ONOFF', true);
} else {
logger.debug('El clima no necesita encenderse');
}
return devices.read('CLIMA', 'ONOFF');
}
Nota: Cuando la función recibe exáctamente un parámetro, los paréntesis pueden ser omitidos, por ejemplo: text => logger.debug(text) es una arrow function válida.
Var, let y const
En
Las variables declaradas con let y const solo existen en el bloque que se definen (es decir, lo encerrado por llaves { y }). Las reglas sobre variables definidas con var son más complejas y escapan de la intención de este documento.
La diferencia entre let y const es que las "variables" asignadas con const no pueden cambiar de valor.
const demostracion = (parametro) => {
if(parametro !== null) {
const grande = parametro > 1000;
let pequeno = parametro < 10;
if(grande) {
grande = parametro * 1000; // -> Error por reasignar constante
} else if (pequeno) {
pequeno = pequeno / 10; // OK
}
}
// grande y pequeno no existen aquí, si se hubiesen definido como var sí existirían en este punto
logger.debug('grande es', grande); // -> Error: grande is undefined
}
Comparaciones (==, !=, === y !==)
Se recomienda usar siempre los comparadores de tres símbolos (=== y !==). Estos comprueban que el valor sea exáctamente el mismo. Las versiones más laxas != y == intentan convertir tipos de dato para hacer comparaciones flexibles, y pueden resultar en errores inesperados, por ejemplo:
1 === '1' // false
1 == '1' // true
0 === [] // false
0 == [] // true
// Sin embargo... Boolean(0) -> false y Boolean([]) -> true
Manejo de errores (excepciones)
A pesar del nombre, los errores de scripts pueden suceder en el funcionamiento normal del sistema. Por ejemplo, un error sería intentar escribir o leer sobre una variable que se encuentra fuera de servicio. Los errores sirven para notificar al programador que ha ocurrido una situación que habría que contemplar de forma diferente.
Si un error no es manejado (es decir, no se captura y especifica qué hacer en caso de que suceda) el script finalizará prematuramente, sin ejecutar las lineas posteriores al error dentro del mismo bloque.
Los errores no manejados son registrados en el log del script y generan una alerta. De esta forma se puede saber que una circunstancia inesperada no ha sido manejada correctamente.
La forma habitual de manejar errores es poniendo el código que puede lanzar errores en una estructura try...catch:
let lectura;
try {
// Código que puede generar errores
lectura = devices.read('variable', 'problematica');
// Si la línea anterior lanza un error, lo siguiente nunca se ejecutará:
logger.debug('He podido leer la variable problemática', lectura);
} catch(error) {
// Código que se ejecuta cuando ocurre un error
logger.warn('Problema leyendo la variable problematica', error);
}
// Lo que esté fuera de la estructura continúa ejecutándose con normalidad, por eso es importante dejar cualquier variable necesaria en un estado consistente si se quiere seguir operando después de un bloque try...catch
Async/await
Algunos métodos disponibles dentro de los scripts son incompatibles con el uso de async/await (por ejemplo devices.read() o alerts.create()).
Por ello, se recomienda no hacer uso de esta característica en los scripts de Promises o async/await.
Como regla general, el código que sigue a una línea await lanzará un error cuando llame a alguno de los métodos internos de
Valores falsy/truty (ciertos o falsos)
En algunos casos se requieren valores que sean true o false. Sin embargo, por la naturaleza de tipado suave del lenguaje, valores que no sean estríctamente uno de esos dos también son aceptados.
En estos casos, es importante tener claras las equivalencias que va a producir el lenguaje, para evitar dar por "cierto" un valor que no lo es.
En este sentido, sólo los siguientes valores son equivalentes a false:
- false
- null
- undefined (en algunos casos, el valor devuelto al acceder a posiciones o propiedades no existentes. También se puede asignar explícitamente)
- 0
- NaN (Not a Number, resultado de realizar operaciones aritméticas sin solución formal)
- "" o '' (Texto vacío, no incluye textos aparentemente vacíos cómo " " o "\n" que solo contengan espacios, tabuladores o carácteres no visibles)
El resto de valores tomarán valor cierto (equivalen a true), incluyendo los siguientes (sólo por señalar algunos que pueden llevar a confusión):
- "0" (Texto que contiene una letra cero
0, no confundir con el número 0). Para convertir un número en representación texto a valornumber, anteponga un símbolo de suma+, por ejemplo:+"123"devuelve el valor numérico123 - {} (Objeto vacío, sin ninguna propiedad)
- [] (Lista/array vacíos). Para evaluar si una lista está vacía se puede acceder a su propiedad
lengthque devuelve un número entero con el tamaño de la lista - " " (Texto con un espacio)
- "false" (Nuevamente, las cadenas de texto pueden llevar a engaño)