034.2 Lección 1
Certificación: |
Conceptos básicos de desarrollo web |
---|---|
Versión: |
1.0 |
Tema: |
034 Programación JavaScript |
Objetivo: |
034.2 Estructuras de datos en JavaScript |
Lección: |
1 de 1 |
Introducción
Los lenguajes de programación, como los lenguajes naturales, representan la realidad a través de símbolos que se combinan en declaraciones significativas. La realidad representada por un lenguaje de programación son los recursos de la máquina, como las operaciones del procesador, los dispositivos y la memoria.
Cada uno de los innumerables lenguajes de programación adopta un paradigma para representar información. JavaScript adopta las convenciones típicas de los lenguajes de alto nivel, donde la mayoría de los detalles, como la asignación de memoria, están implícitos, lo que permite al programador centrarse en el propósito del script en el contexto de la aplicación.
Lenguajes de alto nivel
Los lenguajes de alto nivel proporcionan reglas abstractas para que el programador necesite escribir menos código para expresar una idea. JavaScript ofrece formas convenientes de hacer uso de la memoria de la computadora, utilizando conceptos de programación que simplifican la escritura de prácticas recurrentes y que generalmente son suficientes para el propósito del desarrollador web.
Note
|
Aunque es posible utilizar mecanismos especializados para un acceso meticuloso a la memoria, los tipos de datos más simples que veremos son de uso más general. |
Las operaciones típicas en una aplicación web consisten en solicitar datos a través de alguna instrucción JavaScript y almacenarlos para ser procesados y eventualmente presentados al usuario. Este almacenamiento es bastante flexible en JavaScript, con formatos de almacenamiento adecuados para cada propósito.
Declaración de constantes y variables
La declaración de constantes y variables para contener datos es la piedra angular de cualquier lenguaje de programación. JavaScript adopta la convención de la mayoría de los lenguajes de programación, asignando valores a constantes o variables con la sintaxis name = value
. La constante o variable de la izquierda toma el valor de la derecha. El nombre de la constante o variable debe comenzar con una letra o un guión bajo.
No es necesario indicar el tipo de datos almacenados en la variable, porque JavaScript es un lenguaje de escritura dinámico. El tipo de variable se infiere del valor que se le asigna. Sin embargo, es conveniente designar ciertos atributos en la declaración para garantizar el resultado esperado.
Note
|
TypeScript es un lenguaje inspirado en JavaScript que, al igual que los lenguajes de bajo nivel, le permite declarar variables para tipos específicos de datos. |
Constantes
Una constante es un símbolo que se asigna una vez cuando se inicia el programa y nunca cambia. Las constantes son útiles para especificar valores fijos, como definir la constante PI
como 3.14159265, o COMPANY_NAME
para contener el nombre de su empresa.
En una aplicación web, por ejemplo, tome un cliente que recibe información meteorológica de un servidor remoto. El programador puede decidir que la dirección del servidor debe ser constante, porque no cambiará durante la ejecución de la aplicación. Sin embargo, la información de temperatura puede cambiar con cada nueva llegada de datos del servidor.
El intervalo entre consultas realizadas al servidor también se puede definir como una constante, que se puede consultar desde cualquier parte del programa:
const update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
Cuando se invoca, la función setup_app()
muestra el mensaje Update every 10 minutes
en la consola. El término const
colocado antes del nombre update_interval
asegura que su valor seguirá siendo el mismo durante toda la ejecución del script. Si se intenta restablecer el valor de una constante, se emite un error TypeError: Assignment to constant variable
.
Variables
Sin el término const
, JavaScript asume automáticamente que update_interval
es una variable y que su valor puede modificarse. Esto es equivalente a declarar la variable explícitamente con var
:
var update_interval;
update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
Tenga en cuenta que aunque la variable update_interval
se definió fuera de la función, se accedió desde dentro de la función. Cualquier constante o variable declarada fuera de funciones o bloques de código definidos por llaves ({}
) tiene alcance global; es decir, se puede acceder a ellla desde cualquier parte del código. Lo contrario no es cierto: una constante o variable declarada dentro de una función tiene ámbito local, por lo que es accesible solo desde el interior de la propia función. Los bloques de código delimitados por corchetes, como los que se encuentran en las estructuras de decisión if
o los bucles for
, delimitan el alcance de las constantes, pero no de las variables declaradas como var
. El siguiente código, por ejemplo, es válido:
var success = true;
if ( success == true )
{
var message = "Transaction succeeded";
var retry = 0;
}
else
{
var message = "Transaction failed";
var retry = 1;
}
console.log(message);
La declaración console.log (message)
puede acceder a la variable message
, aunque se haya declarado dentro del bloque de código de la estructura if
. No sucedería lo mismo si message
fuera constante, como se muestra en el siguiente ejemplo:
var success = true;
if ( success == true )
{
const message = "Transaction succeeded";
var retry = 0;
}
else
{
const message = "Transaction failed";
var retry = 1;
}
console.log(message);
En este caso, se emitiría un mensaje de error de tipo ReferenceError: message is not defined
y se detendría el script. Si bien puede parecer una limitación, restringir el alcance de las variables y constantes ayuda a evitar la confusión entre la información procesada en el cuerpo del script y en sus diferentes bloques de código. Por esta razón, las variables declaradas con let
en lugar de var
también tienen un alcance restringido por los bloques delimitados por llaves. Existen otras diferencias sutiles entre declarar una variable con var
o con let
, pero la más significativa se refiere al alcance de la variable, como se analiza aquí.
Tipos de valores
La mayoría de las veces, el programador no necesita preocuparse por los tipos de datos almacenados en variables, porque JavaScript los identifica automáticamente con uno de sus tipos primitivos durante la primera asignación de un valor a la variable. Sin embargo, algunas operaciones pueden ser específicas de un tipo de datos u otro y pueden dar lugar a errores cuando se utilizan sin criterio. Además, JavaScript ofrece tipos estructurados que le permiten combinar más de un tipo primitivo en un solo objeto.
Tipos primitivos
Las instancias de tipo primitivo corresponden a variables tradicionales, que almacenan solo un valor. Los tipos se definen implícitamente, por lo que el operador typeof
se puede utilizar para identificar qué tipo de valor se almacena en una variable:
console.log("Undefined variables are of type", typeof variable);
{
let variable = true;
console.log("Value `true` is of type " + typeof variable);
}
{
let variable = 3.14159265;
console.log("Value `3.14159265` is of type " + typeof variable);
}
{
let variable = "Text content";
console.log("Value `Text content` is of type " + typeof variable);
}
{
let variable = Symbol();
console.log("A symbol is of type " + typeof variable);
}
Este script mostrará en la consola qué tipo de variable se utilizó en cada caso:
Variables indefinidas son del tipo undefined Valor `true` es de tipo booleano Valor `3.114159265` es del tipo numérico Valor `Text content` es del tipo string Un símbolo es del tipo symbol
Observe que la primera línea intenta encontrar el tipo de una variable no declarada. Esto hace que la variable dada se identifique como undefined
. El tipo symbol
es el primitivo menos intuitivo. Su propósito es proporcionar un nombre de atributo único dentro de un objeto cuando no es necesario definir un nombre de atributo específico. Un objeto es una de las estructuras de datos que veremos a continuación.
Tipos estructurados
Si bien los tipos primitivos son suficientes para escribir rutinas simples, existen inconvenientes en su uso exclusivo en aplicaciones más complejas. Una aplicación de comercio electrónico, por ejemplo, sería mucho más difícil de escribir, porque el programador necesitaría encontrar formas de almacenar listas de elementos y valores correspondientes utilizando solo variables con tipos primitivos.
Los tipos estructurados simplifican la tarea de agrupar información de la misma naturaleza en una sola variable. Una lista de artículos en un carrito de compras, por ejemplo, se puede almacenar en una sola variable de tipo array:
let cart = ['Milk', 'Bread', 'Eggs'];
Como se demuestra en el ejemplo, una serie de elementos se designa con corchetes. El ejemplo ha llenado el arreglo con tres valores de cadena literales, de ahí el uso de comillas simples. Las variables también se pueden usar como elementos en un arreglo, pero en ese caso deben designarse sin comillas. El número de elementos en un arreglo se puede consultar con la propiedad length
:
let cart = ['Milk', 'Bread', 'Eggs'];
console.log(cart.length);
El número 3
se mostrará en la salida de la consola. Se pueden agregar nuevos elementos al arreglo con el método push ()
:
cart.push('Candy');
console.log(cart.length);
Esta vez, la cantidad mostrada será 4
. Se puede acceder a cada elemento de la lista por su índice numérico, comenzando con 0
:
console.log(cart[0]);
console.log(cart[3]);
La salida que se muestra en la consola será:
Milk Candy
Así como puede usar push()
para agregar un elemento, puede usar pop()
para eliminar el último elemento de un arreglo.
No es necesario que los valores almacenados en un arreglo sean del mismo tipo. Es posible, por ejemplo, almacenar la cantidad de cada artículo a su lado. Una lista de la compra como la del ejemplo anterior se podría construir de la siguiente manera:
let cart = ['Milk', 1, 'Bread', 4, 'Eggs', 12, 'Candy', 2];
// Item indexes are even
let item = 2;
// Quantities indexes are odd
let quantity = 3;
console.log("Item: " + cart[item]);
console.log("Quantity: " + cart[quantity]);
La salida que se muestra en la consola después de ejecutar este código es:
Item: Bread Quantity: 4
Como ya habrá notado, combinar los nombres de los elementos con sus respectivas cantidades en un solo arreglo puede no ser una buena idea, porque la relación entre ellos no es explícita en la estructura de datos y es muy susceptible a errores (humanos). Incluso si se usara un arreglo para los nombres y otro aarreglo para las cantidades, mantener la integridad de la lista requeriría el mismo cuidado y no sería muy productivo. En estas situaciones, la mejor alternativa es utilizar una estructura de datos más apropiada: un objeto.
En JavaScript, una estructura de datos de tipo objeto le permite vincular propiedades a una variable. Además, a diferencia de un arreglo, los elementos que componen un objeto no tienen un orden fijo. Un artículo de la lista de compras, por ejemplo, puede ser un objeto con las propiedades name
y quantity
:
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
Este ejemplo muestra que un objeto se puede definir usando llaves ({}
), donde cada par de propiedad/valor está separado por dos puntos y las propiedades por comas. La propiedad es accesible en el formato variable.property, como en item.name
, tanto para lectura como para asignar nuevos valores. La salida que se muestra en la consola después de ejecutar este código es:
Item: Milk Quantity: 1
Finalmente, cada objeto que representa un artículo puede incluirse en el arreglo de la lista de compras. Esto se puede hacer directamente al crear la lista:
let cart = [{ name: 'Milk', quantity: 1 }, { name: 'Bread', quantity: 4 }];
Como antes, un nuevo objeto que representa un elemento se puede agregar más tarde al arreglo:
cart.push({ name: 'Eggs', quantity: 12 });
Ahora se accede a los elementos de la lista por su índice y su nombre de propiedad:
console.log("Third item: " + cart[2].name);
console.log(cart[2].name + " quantity: " + cart[2].quantity);
La salida que se muestra en la consola después de ejecutar este código es:
third item: eggs Eggs quantity: 12
Las estructuras de datos permiten al programador mantener su código mucho más organizado y fácil de mantener, ya sea por el autor original o por otros programadores del equipo. Además, muchas salidas de las funciones de JavaScript están en tipos estructurados, que deben ser manejados correctamente por el programador.
Operadores
Hasta ahora, prácticamente solo hemos visto cómo asignar valores a las variables recién creadas. Tan simple como es, cualquier programa realizará varias manipulaciones en los valores de las variables. JavaScript ofrece varios tipos de operadores que pueden actuar directamente sobre el valor de una variable o almacenar el resultado de la operación en una nueva variable.
La mayoría de los operadores están orientados a operaciones aritméticas. Para aumentar la cantidad de un artículo en la lista de compras, por ejemplo, simplemente use el operador de adición +
:
item.quantity = item.quantity + 1;
El siguiente fragmento imprime el valor de item.quantity
antes y después de la adición. No mezcle las funciones del signo más en el fragmento. Las declaraciones console.log
usan un signo más para combinar dos cadenas.
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
item.quantity = item.quantity + 1;
console.log("New quantity: " + item.quantity);
La salida que se muestra en la consola después de ejecutar este código es:
Item: Milk Quantity: 1 New quantity: 2
Tenga en cuenta que el valor almacenado previamente en item.quantity
se utiliza como operando de suma: item.quantity = item.quantity + 1
. Solo después de que se completa la operación, el valor en item.quantity
se actualiza con el resultado de la operación. Este tipo de operación aritmética que involucra el valor actual de la variable de destino es bastante común, por lo que existen operadores abreviados que le permiten escribir la misma operación en un formato reducido:
item.quantity += 1;
Las otras operaciones básicas también tienen operadores abreviados equivalentes:
-
a = a - b
es equivalente aa -= b
. -
a = a * b
es equivalente aa *= b
. -
a = a / b
es equivalente aa /= b
.
Para la suma y la resta, hay un tercer formato disponible cuando el segundo operando es solo una unidad:
-
a = a + 1
es equivalente aa++
. -
a = a - 1
es equivalente aa--
.
Se puede combinar más de un operador en la misma operación y el resultado se puede almacenar en una nueva variable. Por ejemplo, la siguiente declaración calcula el precio total de un artículo más un costo de envío:
let total = item.quantity * 9.99 + 3.15;
El orden en el que se realizan las operaciones sigue el orden de precedencia tradicional: primero se realizan las operaciones de multiplicación y división, y solo entonces se realizan las operaciones de suma y resta. Los operadores con la misma precedencia se ejecutan en el orden en que aparecen en la expresión, de izquierda a derecha. Para anular el orden de precedencia predeterminado, puede utilizar paréntesis, como en a * (b + c)
.
En algunas situaciones, el resultado de una operación ni siquiera necesita almacenarse en una variable. Este es el caso cuando desea evaluar el resultado de una expresión dentro de una declaración if
:
if ( item.quantiy % 2 == 0 )
{
console.log("Quantity for the item is even");
}
else
{
console.log("Quantity for the item is odd");
}
El operador %
(módulo) devuelve el resto de la división del primer operando por el segundo operando. En el ejemplo, la instrucción if
verifica si el resto de la división de item.quantity
por 2
es igual a cero, es decir, si item.quantity
es un múltiplo de 2.
Cuando uno de los operandos del operador +
es una cadena, los otros operandos son coercidos en cadenas y el resultado es una concatenación de cadenas. En los ejemplos anteriores, este tipo de operación se utilizó para concatenar cadenas y variables en el argumento de la declaración console.log
.
Es posible que esta conversión automática no sea el comportamiento deseado. Un valor proporcionado por el usuario en un campo de formulario, por ejemplo, puede identificarse como una cadena, pero en realidad es un valor numérico. En casos como este, la variable debe convertirse primero en un número con la función Number()
:
sum = Number(value1) + value2;
Además, es importante verificar que el usuario haya proporcionado un valor válido antes de continuar con la operación. En JavaScript, una variable sin un valor asignado contiene el valor null
. Esto permite al programador usar una declaración de decisión como if ( value1 == null )
para verificar si a una variable se le asignó un valor, independientemente del tipo de valor asignado a la variable.
Ejercicios guiados
-
Un arreglo es una estructura de datos presente en varios lenguajes de programación, algunos de los cuales solo permiten arreglos con elementos del mismo tipo. En el caso de JavaScript, ¿es posible definir un arreglo con elementos de diferentes tipos?
-
Basado en el ejemplo
let item = { name: 'Milk', quantity: 1 }
para un objeto en una lista de compras, ¿cómo podría declararse este objeto para incluir el precio del artículo? -
En una sola línea de código, ¿cuáles son las formas de actualizar el valor de una variable a la mitad de su valor actual?
Ejercicios de exploración
-
En el siguiente código, ¿qué valor se mostrará en la salida de la consola?
var value = "Global"; { value = "Location"; } console.log(value);
-
¿Qué sucederá cuando uno o más de los operandos involucrados en una operación de multiplicación sea una cadena?
-
¿Cómo es posible eliminar el elemento
Eggs
de la matrizcart
declarada conlet cart = ['Milk', 'Bread', 'Eggs']
?
Resumen
Esta lección cubre el uso básico de constantes y variables en JavaScript. JavaScript es un lenguaje de escritura dinámico, por lo que el programador no necesita especificar el tipo de variable antes de configurarlo. Sin embargo, es importante conocer los tipos primitivos del lenguaje para asegurar el resultado correcto de las operaciones básicas. Además, las estructuras de datos como arreglos y objetos combinan tipos primitivos y permiten al programador construir variables compuestas más complejas. Esta lección abarca los siguientes conceptos y procedimientos:
-
Comprensión de constantes y variables
-
Alcance de variables
-
Declaración de variables con
var
ylet
-
Tipos primitivos
-
Operadores aritméticos
-
Arreglos y objetos
-
Coerción y conversión de tipos
Respuestas a los ejercicios guiados
-
Un arreglo es una estructura de datos presente en varios lenguajes de programación, algunos de los cuales solo permiten arreglos con elementos del mismo tipo. En el caso de JavaScript, ¿es posible definir un arreglo con elementos de diferentes tipos?
Sí, en JavaScript es posible definir arreglos con elementos de diferentes tipos primitivos, como cadenas y números.
-
Basado en el ejemplo
let item = { name: 'Milk', quantity: 1 }
para un objeto en una lista de compras, ¿cómo podría declararse este objeto para incluir el precio del artículo?let item = { name: 'Milk', quantity: 1, price: 4.99 };
-
En una sola línea de código, ¿cuáles son las formas de actualizar el valor de una variable a la mitad de su valor actual?
Se puede usar la propia variable como operando,
value = value / 2
, o el operador abreviado/=
:value /= 2
.
Respuestas a los ejercicios de exploración
-
En el siguiente código, ¿qué valor se mostrará en la salida de la consola?
var value = "Global"; { value = "Location"; } console.log(value);
Location
-
¿Qué sucederá cuando uno o más de los operandos involucrados en una operación de multiplicación sea una cadena?
JavaScript asignará el valor
NaN
(No es un número) al resultado, lo que indica que la operación no es válida. -
¿Cómo es posible eliminar el elemento
Eggs
de la matrizcart
declarada conlet cart = ['Milk', 'Bread', 'Eggs']
?Las matrices en javascript tienen el método
pop()
, que elimina el último elemento de la lista:cart.pop()
.