Guayaquil, miércoles 13 de sept.
del 2023
Inicio Portafolio Dudú WebCode Artículos
#Javascript, #DOMJs, #webinteractiva, #Interfaces, #duduromeroa, #Guayaquil
J A V A S C R I P T
Programación para web (1/8): Javascript,
expresiones, declaraciones, tipos de
valores
Esta sección aportará con estudio y análisis de la sintaxis del lenguaje de
programación Javascript, creado en sus fases iniciales por el estadounidense
Brendan Eich en 1995.
Por Eduardo J. Romero Andrade
ACTUALIZADO: Febrero 8 del 2023 | Guayaquil
CONTENIDO
Introducción: código y sintaxis en programación
¿Qué es Javascript?
Expresiones y declaraciones en JS
Invocar valores
Sentencia return
Hoisting
Tipos de valores: números
Precedencia aritmética
Anterior Avanzar
BREVE INTRODUCCIÓN: CÓDIGO Y SINTAXIS EN PROGRAMACIÓN
Los lenguajes de programación son el idioma que las computadores interpretan
para ejecutar acciones entre máquina y usuario, como calcular y mostrar la inter-
acción y las animaciones durante un videojuego.
Programar significa crear procesos e instrucciones que sean reconocibles por
sistemas. Programar también refiere a insertar, leer, transformar y mostrar datos
hacia un sistema.
A diferencia del lenguaje humano –variado, subjetivo– un lenguaje de programa-
ción debe ser lógico y preciso.
Por ejemplo, en lenguaje humano, podemos pedirle a otra persona lo siguiente:
"Por favor, pásame la manzana que está encima de la mesa".
La respuesta a ese pedido dependerá de factores como el idioma –la otra perso-
na debe entenderlo–, el contexto –si la manzana es real, imaginaria o una repre-
sentación, como un dibujo–, y la aceptación de ese pedido –es decir, que otra
persona esté presente y acepte ejecutar la acción–.
El anterior requerimiento podría expresarse, con algunas limitaciones, de la si-
guiente forma mediante programación falsa, que es una forma de plantear un
problema lógico de programación en forma de afirmaciones breves, alejadas de
la sintaxis de un verdadero lenguaje de programación:
Código falso
INICIO
Objeto : manzana;
método : pedido(objeto);
para cada inicio de método : alertar y confirmar;
si método existe{
activar método;
confirmar }
si no existe {
alertar
}
pedido(objeto){
entender el pedido,
buscar manzana,
si manzana existe{
seguir
} si no existe {
alertar
}
recoger manzana,
entregar manzana
}
alerta : metodo hallado;
alerta : metodo activado
alerta : metodo finalizado
alerta : manzana entregada
FIN
En otras palabras, un ser humano podría comprender una orden, interpretarla,
pedir aclaraciones y confirmaciones antes y después de realizarla. Un sistema,
en cambio, requiere recibir las órdenes en un lenguaje previamente interpretado,
actualizado, dando precisiones de datos y estableciendo acciones de confirma-
ción, todo eso sin ambigüedades y con una economía de palabras muy limita-
da. El lenguaje que la web interpreta para recibir datos, órdenes y acciones para
alterar esos datos es Javascript.
¿QUÉ ES JAVASCRIPT?
Javascript –Java, por la referencia a otro lenguaje de programación; y script, an-
glicismo usado para definir que algo es redactado según ciertas normas– es un
lenguaje de programación que se interpreta y se ejecuta desde la internet y des-
de toda página web alojada en ella.
De aquí en adelante, explicaré progresivamente y desde un nivel
intermedio-avanzado muchas de las características de JS.
Si el lector necesita referencias iniciales de HTML y JS, recomiendo revisar
este vínculo o cualquier otro recurso que explique los fundamentos más
básicos de esas tecnologías.
Finalmente, en la bibliografía –al final– adjunto los libros y sitios web
consultados.
EXPRESIÓN, INICIALIZACIÓN, DECLARACIÓN
Expresar o sentenciar es usar una unidad de código para crear valores. Las ex-
presiones se separan con punto y coma. Por ejemplo, en matemáticas la expre-
sión '10 + 100;' crea el valor 110.
Las declaraciones vinculan un nombre identificador a un valor de texto o numéri-
co. Declarar también refiere a crear o identificar una función. Una declaración
SIN un valor inicial es leída por el sistema como undefined.
Inicializar es dar un valor –numérico o alfanumérico– a una expresión.
Entonces, expresar es usar el código para crear datos; declarar es identificar un
valor para luego referenciarlo; e inicializar es dar un valor a un identificador.
/* Declarador de variable: expresión mínima que
por sí sola no crea valores. */
var;
// Declaración mínima
var num;
// Inicialización: dar un valor
var num = 20;
// Expresión y declaración: crea un resultado
var num = 20+20;
// -> 40
/* Expresiones que declaran identificadores
y crean inicialización con valores */
var nomb = "Edu",
var apell = "Romero"
var edad = 45;
/* Expresión condicional formado por
otra expresión con dato declarado */
if (nombre == "dudu") { alert("Hola Dudú"); }
// Muestra 'Hola Dudú'
Para w3schools cada sentencia o declaración puede contener:
Valores
Operadores
Expresiones
Palabras clave
Comentarios
INVOCAR VALORES
En JS un valor debe ser declarado –darle un identificador o nombre–; para luego
ser inicializado –darle un valor inicial– y para finalmente ser referenciado (recu-
perar ese valor en memoria para luego operar).
CUIDADO: Cada declaración debe tener un nombre identificador diferente.
Mayúsculas y minúsculas se leen diferente.
// Identificador con mayúsculas
var NOMBREPERSONA = 10;
// Identificador con inicia con guión
var _nombrePersona = 20
// Identificador con variantes
var nombrEPersonA = 10;
// Invocamos valores
console.log(NOMBREPERSONA);
// 10
console.log(_nombrePersona);
// 20
console.log(NOMBREPERSONA == nombrEPersonA);
/* true. Ambos identificadores
tienen el mismo valor */
Abajo, en las dos primeras líneas los valores se guardan en memoria pero aún
no son accedidos. Luego se invoca solo el nombre identificador correcto de cada
valor.
var cancionQueMegusta = "Woodstock"
var autor = "CSN";
/* Valores invocados */
/* Los valores se invocan desde el
identificador o nombre de la variable.
NO desde el valor */
alert("La canción que me gusta es " +
cancionQueMegusta +
"y la toca " +
autor );
/* Mensaje: La canción que
me gusta es Woodstocky la toca CSN */
SENTENCIA RETURN
return permite que una expresión retorne un valor especificado dentro de una
función.
No es necesario usar la función console.log() antes del return. Recordar que
console.log() devuelve un dato para evaluación solamente.
return no siempre necesitará de una expresión para devolver un valor válido. Ya que
también puede devolver un valor undefined aunque no se devuelva ningún otro
valor.
En Javascript
/* Esta función retorna undefined
porque a 'return' no le sigue una expresión */
function num(x) {
x * x;
return;
}
console.log(num(5));
//-> undefined
// ****** Esta expresión sí retorna un valor *****
function num(x) {
return x * x;
}
let dato = num(5);
console.log(dato);
//-> 25
Por otro lado, la diferencia entre usar console.log y la sentencia return en la si-
guiente: la función console.log() si bien muestra un valor en consola, no devuel-
ve un valor a un invocador o llamado de referencia ni tampoco finaliza la
ejecución de una función. En cambio, la sentencia return sí prepara un valor
para ser invocado desde fuera de la función y sí detiene la ejecución de la fun-
ción luego de ser invocada.
console.log() no devuelve un valor a un invocador externo ni detiene la ejecución
de una función; pero return sí lo hace.
/* La siguiente función usa console.log()
para mostrar un valor. Ejecutará cada invocación.*/
function a(b){
let x = b + b;
console.log(x);
console.log(x+x);
console.log(x*x);
console.log(x/x);
// return x;
}
// Invocación
a(10);
//-> 20
//-> 40
//-> 400
//-> 1
/* ERROR: No obtiene el valor de 'x' */
// console.log(x);
// ReferenceError
/* usando return; */
function a(b){
let x = b + b;
return x;
// Esto ya no se ejecuta
console.log(x);
console.log(x+x);
console.log(x*x);
console.log(x/x);
}
console.log(a(10));
// 20
Si return no halla un valor retornará la propiedad undefined. Eso indica que
un valor no ha sido asignado a una variable o no ha sido identificado con un
nombre, es decir; no está declarado.
Para Svekis y Putten[5], gracias a return todo valor creado dentro de una fun-
ción –es decir, un valor local– es accedido desde cualquier sitio del código. Sin
return, se ejecutará la función pero existirá siempre un valor sin definir.
/* Función con parámetro para
insertar un valor */
function numero(a){
/* Altera valor insertado al
ingresar valor de argumento */
let operado = a*a;
// Se pide mostrar argumento
console.log(operado);
}
// Invocar función y dar argumento
console.log(numero(3));
// -> Muestra valor 9
// -> Pero tamb muestra undefined
Con return al final de la función nada queda pendiente, pero solo se podrá eje-
cutar un envío y una sola vez.
Usando una función con return para mostrar un valor en la pantalla en vez de la
consola:
En HTML
<!-- Se usa un elemento HTML para usarlo como nodo -->
<p id="mostrar"></p>
En Javascript
// Definir función, argumentos y operación
function operar(a, b) {
return a * b;
}
/* Crear variable y guardar función con argumentos */
/* Ojo aquí ya estamos invocando */
let x = operar(4, 3);
/* (ojo igualdad): Al apuntar a un elemento id 'mostrar',
insertar el resultado de la función 'operar' */
document.getElementById("mostrar").innerHTML = x;
// -> Se muestra en pantalla el valor 12
Otras formas en que return 'entrega y detiene ejecución' son las siguientes:
return;
return true;
return false;
return valor;
return valorA * valorB / valorC;
return function calc(x) { return x * 42; };
// Función con parámetro
function nombre(a){
// Solo devuelve booleano true
return true;
}
// Invoca función con un valor cualquiera
console.log(nombre(11));
// -> true
En el ejemplo inferior, el único trabajo de la función 'ejecuta()' y su parámetro 'a'
es la de multiplicar un valor por mil. Una vez retornado -de forma invisible para
nosotros- ese valor a la invocación 'console.log(ejecuta(10));' solo la función
'console.log()' mostrará ese valor. El resto del contenido de la función no será
ejecutado.
Finalmente, return es igual a un despachador de correo que enviará el paquete
solo cuando él este presente y cuando la orden –la invocación– este activa.
// CON RETURN
function ejecuta(a){
/* Una vez devuelta esta operación,
nada más será ejecutado */
return a * 1000;
// Lo siguiente ya no será ejecutado
return a * 2000;
console.log("Holaaaa!");
var numerote = 2000;
return console.log(numerote);
}
// Invoco e inserto argumento
console.log(ejecuta(10));
// --> 10000
En otro ejemplo: accedemos primero al valor del argumento y luego, al valor del
mismo argumento desde return, pero operado. La función se cierra luego de eso:
// Función con parámetro
function nombre(a){
// Accedemos al valor de 'a'
console.log(a);
// Devolvemos el valor de 'a' operado
return a*a;
}
// Invoca función con un valor cualquiera
console.log(nombre(5));
// -> 5 --> El valor de 'a'
// -> 25 --> El valor de 'a' multiplicado
En cambio, acceder al valor del argumento desde fuera de la función y sin re-
turn dará error.
function nombre(a){
// Devolvemos el valor de 'a' operado
return a*a;
}
// Invoca función con un valor cualquiera
console.log(nombre(5));
// DA ERROR: 'a' no está definido
console.log(a);
/* Es imposible llamar al valor de 'a'
desde fuera de la función 'nombre*/
HOISTING: ALZADO DE VALORES
El anglicismo 'hoisting' refiere a alzar, elevar o izar algo. He inventado un verbo
en español para eso: 'primerizar'. En JS el hoisting refiere a cómo se referencian
valores o funciones que aún no han sido declaradas.
En JS, hoisting o primerizar –según mi nuevo verbo– significa poner en primera
línea aquella expresión declarada que debería ser leída primero, pero que se ha
declarado mucho después de su invocación:
En Javascript
// Expresión 'A' invocada aquí
// Código.....
// Código.....
// Código.....
/* Expresión 'A' declarada aquí: JS la manda
a la primera línea para ser leída y operada.*/
/* Invocamos valor de 'x'. Este valor aún no existe,
por lo que dará un mensaje de 'undefined' */
console.log(x);
// -- Solo lo declarado se primeriza --
/* Aquí declaramos a 'x' como una variable; pero aún
no la hemos inicializado con un valor. Sin embargo,
'x' ya está con hoisting, es decir, está lista
para ser leída en caso de ser alimentada con un valor */
var x;
/* Aquí 'x' ya está inicializado.
Pero ese valor no esta primerizado,
solo su declaración.
Por lo tanto, 'x' solo le toca leer el valor de 10 */
x = 10;
/* Por lo que al invocar 'x', ahora sí,
podemos obtener el valor y mostrarlo */
console.log(x);
//-> 10
El hoisting solo eleva las declaraciones; no eleva inicializaciones:
var x -> valor solo declarado. Puede ser elevado
x = 5 -> valor solo inicializado. No puede ser elevado
var x = 5 -> valor declarado e inicializado. No puede ser elevado
¿Por qué solo se elevan las declaraciones y no las inicializaciones?:
Para permitir que solamente las declaraciones sean invocadas desde cualquier
ubicación en el código, aún cuando no hayan sido declaradas todavía.
Elevar una expresión inicializada obligaría a evaluarla primero sin saber, por
ejemplo, qué tipo de variable o función son o si tienen un valor sin errores de
sintaxis o de dato.
En Javascript
// PRIMERIZADO CON VALOR DECLARADO
// Se invoca algo que aún no se declara
console.log(x);
/* Se declara valor: pero solo se sube el
identificador 'x', no su valor inicializado */
var x = 10;
// ReferenceError: x is not defined
/* Para solucionar eso, primero se debe
declarar e inicializar; luego, invocar*/
var x = 10;
console.log(x);
//-> 10
/* Aquí no es necesario el hoisting porque
la declaración, la inicialización y la invocación
es lógica y ordenada */
// Declarar
var numero;
// Inicializar
numero = 100;
// Invocar
console.log(numero);
// Otro ejemplo
// Se declara función
function saludo(a){
// Retorna valor
return a;
}
// Se invoca función
console.log(saludo(3));
//-> 3
Luego, probar dónde JS permite el alzado de la expresión desde una función,
una variable inicializada y una variable declarada.
// *** HOISTING CON FUNCIONES ***
// SÍ podemos primero invocar para luego inicializar
saludar("holi");
/* Gracias al hoisting esta función sube
para ser leída primero */
function saludar(a){
console.log(a);
return;
}
//-> holi
//---- ---- ----
// *** HOISTING CON VARIABLES INICIALIZADAS ***
/* NO es posible invocar primero e inicializar después */
console.log(b);
/* ES decir, JS NO eleva lo inicializado */
var b = 100;
// -> undefined. Primero inicializar para luego invocar
//---- ---- ----
// *** HOISTING CON VARIABLES DECLARADAS ***
/* SÍ podemos declarar para luego inicializar */
c = 10;
/* JS SÍ eleva lo declarado */
var c;
// Para luego invocar
console.log(c);
// -> 10
El hoisting no funciona con variables inicializadas –es decir, con variables a las
que YA se les asignó valor:
/* INCORRECTO */
/* Invocar primero...*/
console.log(numero);
/* inicializar después. */
numero = 100;
// ERROR DE REFERENCIA
// _ _ _ _
/* CORRECTO */
/* Inicializar...*/
numero = 100;
/* para luego invocar...*/
console.log(numero);
// -> hola
Según mdn web docs, todo lo declarado es alzado; es decir, llevado a la memo-
ria del sistema para ejecutarlo en orden de declaración.
En otro ejemplo: gracias al hoisting la función 'saludo(a)' es leída como si hubie-
ra estado declarada desde el inicio del código.
// Invoco algo que no está declarado
saludo("Hooli");
//-> ERROR: No definido
// Pero finalmente declaro la función...
function saludo(a){
return console.log(a);
}
// --> Hooli
Declarar es dar un identificador a un tipo de dato.
Inicializar o asignar es dar un valor a esa declaración.
// Se declara una variable pero NO se la inicializa
let numero;
// Viene un bloque de código cualquiera
{
datoCualquiera: 1;
datoCualquiera: 2;
datoCualquiera: 3;
datoCualquiera: 4;
datoCualquiera: 5;
datoCualquiera: 6;
/* Recién aquí se ha
inicializado la variable */
numero = 100;
/* Y aquí se la REinicializó con otro valor */
numero = 100/2;
}
// Aquí se ha invocado la variable
console.log(numero);
// -> 50
/* JS 'lee' el contenido de esa variable
como si esta ya hubiera estado desde el inicio. */
En el ejemplo de abajo, si bien la función 'nombre("Mau")' está colocada después
de su invocación, JS toma esa función y la 'eleva' como si estuviera escrita al
inicio del código.
// El valor recién está declarado e invocado...
// Pero la función 'nombre' aún no está creada
nombre("Mau");
// Mau
// La función recién es creada aquí
function nombre(ingresarNombre) {
console.log(ingresarNombre);
}
// Este código muestra 'Mau'
Todo lo anterior nos lleva a recordar que: una variable dentro de una función –es
decir, con un contexto local– será leída PRIMERO por JS antes que otra variable
ubicada fuera de esa función –es decir, con un contexto global–.
En el ejemplo de abajo, el contenido de la variable 'musico' dentro de la función
es mostrado primero antes que el contenido de la otra variable, con el mismo
nombre y afuera de la función. Esto es porque JS da prioridad a la variable del
primer ámbito. En este ejemplo, el primer ámbito es la función 'mostrar'.
// Identificador en ámbito global
var musico = "Julio Jaramillo";
function mostrar(m){
// Identificador en ámbito local: dentro de función
var musico = "Mireya Cesa";
return musico;
}
/* Llamamos hacia dentro de función */
console.log(mostrar("Crucks n Karnak"));
// --> Mireya Cesa
En otro ejemplo JS leerá como indefinido un valor que haya sido llamado pero
sin haber sido inicializado antes. Similar a decir 'tengo 4 manzanas en la cesta'
sin tener la cesta ni las manzanas.
// Invoco un valor que no ha sido creado aún
console.log(a);
// Aunque lo haya creado luego, tampoco es obtenido
var a = 2;
/* Este código resulta en undefined.
Es decir, se desconoce el contenido
del identificador que está guardando el valor. */
En resumen, el hoisting en JS eleva o primeriza toda declaración –excepto las
inicializaciones– de variable o funciones. Sin embargo, siempre será mejor prác-
tica usar variables o funciones cuando sabemos que ya han sido declaradas.
TIPOS DE VALORES: NÚMEROS
Un tipo es un valor operable para crear otro nuevo valor. Para Antani y
Stefanov[4] "todo lo que no sea tipo de dato es un objeto" en JS. Los tipos son:
Números, literales numéricos, enteros, racionales, decimales, negativos
Algunos números fraccionarios grandes –como Pi– deben ser tomados
como aproximaciones y no como números precisos.[1]
Para Haverbeke "Los valores de tipo string, número y Booleano no son objetos".
Es decir, no guardan propiedades aunque sí contienen algunas que permiten
modificarlos en su longitud o contenido (ver Objetos).
Ya que los números pueden ser infinitos, un computador necesita mayor capaci-
dad de combinaciones. Todo lenguaje de programación moderno, como JS, per-
mite hasta 18 mil trillones de combinaciones numéricas. Esto es, dos números
con 18 ceros, la cantidad posible en sistemas con 64 bits de capacidad [1].
var numeroChiquito = 0.1;
// numeroGrandote = Nueve trillones
/* Separadores literales (guiones bajos
entre cifras)*/
var numeroGrandote = 9000_000_000_000_000;
var numeroTextual = "20";
/* Operaciones con valores
exclusivamente numéricos */
console.log(numeroChiquito + 1); //1.1
/* JS NO permite operar literales
textuales –entre comillas–*/
console.log(numeroTextual + "1"); // 201
// Solo adjunta el número 1, NO lo suma.
PRECEDENCIA ARITMÉTICA (Operator precedence)
La precedencia es la jerarquía aritmética de ejecución de operaciones. Según
ese orden, la multiplicación y la división se ejecutarán antes que las sumas y res-
tas. La suma "siempre se evaluará de izquierda a derecha."
En el ejemplo de abajo, dejemos que la precedencia aritmética pura haga lo
suyo: primero multiplicar, luego sumar y restar.
console.log(1 + 2 + 3 * 10 - 10);
// a) 3 * 10 = 30
// b) 30 + 2 + 1 = 33
// c) 33 - 10 = 23
// Resultado: 23
Otro ejemplos, abajo. Primero divide, luego suma y resta:
console.log( 10 - 5 / 10 + 2);
// a) 5 / 10 = 0.5
// b) 0.5 - 10 = -9.5
// c) -9.5 + 2 = 11.5
// Resp: 11.5
// Primero se multiplica (4*11)
// Luego se suma (44+100)
alert( 100 + 4 * 11);
// R. 144
// Primero se divide
// Luego se suma y se resta
alert( 4 + 8 - 1 + 10 / 2);
// R. 16
// Para un mejor control, agrupar en paréntesis
alert( (4+8)-(1*10) / 2);
// R. 7
El residuo (%) solo devuelve el valor residuo de una división.
// Ejemplo con residuo
var num = 2;
// num dividido para 2
console.log(num % 2);
/* Operador % SOLO arroja el residuo de la división */
// -> 0
/* Si num / 2 da como residuo el cero */
if (num % 2 == 0){
// Si es true
console.log(num + " es par")
// Si es false
} else {console.log(num + "Es impar")
};
// Es par
Subir al inicio Avanzar
BIBLIOGRAFÍA:
[1] Eloquent JavaScript 3ra edición. 2018. Marijn Haverbeke. No starch
press.
[2] MDN Web Docs, Javascript. Mozilla Foundation.
[3] JavaScript: The Definitive Guide. David Flanagan (2020). Editorial
O'Reilly.
[4] Object-Oriented JavaScript Ved Antani, Stoyan Stefanov (2017). Packt
Publishing.
[5] Laurence Lars Svekis, Maaike van Putten. JavaScript from Beginner to
Professional: Learn JavaScript quickly by building fun, interactive, and dy-
namic web apps, games, and pages (2021). Editorial Packt.
https://www.duduromeroa.com | 2023
[email protected] | Guayaquil, Ecuador