Tipos de datos primitivos
Contenidos
Similar a los lenguajes naturales, que tienen verbos, pronombres y sustantivos, los lenguajes de programación vienen con ‘elementos’ básicos que usaremos para construir soluciones más complejas usando estos elementos básicos.
Estas piezas básicas las podemos separar en dos: operadores (asignaciones, bucles, condicionales) y tipos de datos (números, letras, palabras, verdadero, falso, nulo, etc). Dependiendo del propósito del lenguaje estos pueden variar, pero en general harán referencia a ellos como el núcleo imperativo o sus primitivos. Hay lenguajes dónde no hay tipos primitivos como los lenguajes completamente orientados a objetos (Ruby en particular) y otros que tienen muchos tipos primitivos para trabajar conceptos científicos o más abstractos (Julia por ejemplo). Lo importante es que cada vez que debamos ser productivos en un nuevo lenguaje, nos demos el tiempo de entender sus bloques fundamentales antes de pasar a los conceptos más avanzados.
Específicamente en Javascript un primitivo es un dato que no es un objeto, es decir, no tiene métodos (más sobre objetos y métodos en el capítulo 7).
Los primitivos de Javascript son inmutables y no pueden ser alterados, esto es causa de confusión porque las variables que referencian a valores primitivos sí podrían reasignarse, pero el valor primitivo no [1].
En los ejercicios del laboratorio experimentarás con los siguientes elementos primitivos de Javascript
Undefined y Null
Undefined es el valor que el intérprete de Javascript entrega cuando una variable está definida, pero no asignada. La siguiente imágen muestra el comportamiento de una variable no asignada. El intérprete retorna undefined cuando no ha sido asignada. Algo muy diferente a lo que ocurre cuando una variable no está definida, en cuyo caso el intérprete levantará una exceptión de tipo ReferenceError.
var x; console.log(x) // undefined console.log(y) // reference error
Null por otro lado es un valor que nos permite asignar voluntariamente un valor que representa la ausencia de valor. Como regla general podemos indicar que el intérprete de Javascript debería ser el encargado de gestionar el valor undefined y nosotros como programadores podemos utilizar null cuando necesitemos indicar que una variable tiene un valor nulo que podría cambiar durante la ejecución del programa [2].
let y = null; console.log(y); // null
Con frecuencia veremos en frameworks y librerías variables que se inicializan con el valor null para luego actualizar su valor.
!Experimenta!: ¿Qué ocurrirá con las siguientes expresiones?
var i = 1 + undefined console.log(i) var i = 1 + null console.log(i)
Boolean
En JavaScript, un booleano es un tipo de dato que puede tener solo dos valores: verdadero o falso. Los booleanos a menudo se utilizan en sentencias condicionales para determinar si se cumple o no una determinada condición. Por ejemplo, el siguiente código imprimirá “Sí” en la consola si la variable x es mayor que 10, y “No” en caso contrario:
let x = 15; if (x > 10) { console.log("Yes"); } else { console.log("No"); }
Los valores booleanos también se pueden almacenar en variables. Por ejemplo:
let isRaining = true; if (isRaining) { console.log("Bring an umbrella!"); } else { console.log("Enjoy the sunshine!"); }
JavaScript también proporciona varios operadores de comparación que devuelven un valor booleano. Por ejemplo:
let x = 5; let y = 10; console.log(x < y); // true console.log(x == y); // false console.log(x === y); // false
Además, JavaScript también proporciona operadores lógicos como &&
(y), ||
(o), y !
(no) que se pueden utilizar para combinar varias expresiones booleanas y devolver un único valor booleano.
let x = 5; let y = 10; let z = 20; console.log(x < y && x < z); // true console.log(x < y || x < z); // true console.log(!(x < y)); // false
Esos son algunos de los conceptos básicos de los booleanos en JavaScript.
Number
En JavaScript, los números son un tipo de dato primitivo que se utilizan para representar valores numéricos. Los números pueden ser enteros o decimales (conocidos como números de punto flotante) y pueden ser positivos o negativos. Por ejemplo:
var x = 5, y = 3.14, z = -2.7 console.log(typeof(x)) // integer console.log(typeof(y)) // floating point number console.log(typeof(z)) // negative floating point number
JavaScript tiene un único tipo de número, que es un número de punto flotante de precisión doble (64 bits) según el estándar IEEE 754. Esto significa que los números pueden ser muy grandes o muy pequeños y aún así ser representados con precisión.
JavaScript proporciona varios operadores aritméticos para trabajar con números, como +
, -
, *
, /
, %
(módulo) y **
(exponenciación). Por ejemplo:
let a = 5; let b = 2; console.log(a + b); // 7 console.log(a - b); // 3 console.log(a * b); // 10 console.log(a / b); // 2.5 console.log(a % b); // 1 console.log(a ** b); // 25
También se pueden usar los operadores de incremento ++
y decremento --
para aumentar o disminuir un número en 1.
let x = 5; console.log(x++); // 5 console.log(x); // 6 console.log(--x); // 5
JavaScript también proporciona varias funciones matemáticas integradas, como Math.round()
, Math.floor()
, Math.ceil()
, Math.sqrt()
, Math.pow()
, etc. Estas funciones se pueden utilizar para realizar operaciones matemáticas más complejas en los números.
console.log(Math.round(2.5)); // 3 console.log(Math.floor(2.9)); // 2 console.log(Math.ceil(2.1)); // 3 console.log(Math.sqrt(9)); // 3 console.log(Math.pow(2, 3)); // 8
En resumen, los números son un tipo de dato muy importante en JavaScript, y se utilizan en una amplia variedad de operaciones y cálculos.
NaN
NaN
significa “Not a Number”. Es un valor especial en JavaScript que representa la ausencia de un valor numérico. NaN
se devuelve típicamente cuando se realiza una operación matemática en valores no numéricos, o cuando la entrada a una función no está en el formato esperado.
Por ejemplo, las siguientes operaciones devolverán NaN:
console.log(parseFloat("hello world")); // prints NaN console.log(Math.sqrt(-5)); // prints NaN console.log(0/0); // prints NaN
Una cosa importante a tener en cuenta sobre NaN
es que no es igual a ningún valor, incluyéndose a sí mismo. Esto significa que la siguiente comparación devolverá false. Y NaN
es en sí un “number”.
console.log(NaN == NaN); // prints false console.log(typeof(NaN)); // "number"
isNaN
isNaN()
es una función en JavaScript que se utiliza para determinar si un valor es NaN
(Not a Number). La función isNaN()
devuelve true
si el valor pasado como argumento no es un número válido, y false
si es un número válido.
console.log(isNaN(5)); // imprime false console.log(isNaN("hello world")); // imprime true console.log(isNaN(undefined)); // imprime true console.log(isNaN(NaN)); // imprime true
La función isNaN()
también es capaz de determinar si un valor es NaN
si se pasa como una cadena que no puede ser convertida en un número, por ejemplo:
console.log(isNaN("5")); // imprime false console.log(isNaN("5.5")); // imprime false console.log(isNaN("hello")); // imprime true
Es importante mencionar que isNaN()
no siempre funciona como es esperado, ya que puede confundirse con otro tipo de valores, por ejemplo:
console.log(isNaN({})); // imprime true console.log(isNaN([])); // imprime true console.log(isNaN("5a")); // imprime true
En estos casos se recomienda utilizar Number.isNaN()
o isFinite()
para determinar si un valor es un número válido o no.
String
Un string es un tipo de dato que representa una secuencia de caracteres. Los strings pueden ser con comillas simples o dobles, de la siguiente manera:
let firstName = "John"; let lastName = 'Doe';
También puedes utilizar template strings, los cuales están enclavados entre acentos graves ( ` ) y pueden contener expresiones las cuales serán evaluadas y concatenadas
let name = `My name is ${firstName} ${lastName}`; console.log(name); // My name is John Doe
También puedes usar concatenación de strings con el operador +
o el método concat()
para combinar varios strings.
let a = "Hello, "; let b = "world!"; console.log(a + b); // Hello, world! console.log(a.concat(b)); // Hello, world!
Asignación por valor y asignación por referencia
En JavaScript, cuando se asigna un valor a una variable, este valor puede ser un tipo de dato primitivo (como un número o un string) o una referencia a un objeto. La forma en que se asigna el valor a la variable determina si se asigna por valor o por referencia.
La asignación por valor significa que cuando se asigna un valor a una variable, se almacena una copia de ese valor en la ubicación de memoria de la variable. Por ejemplo:
let x = 5; let y = x; x = 10; console.log(x); // 10 console.log(y); // 5
Aquí, cuando se asigna el valor de x
a y
, se almacena una copia del valor 5
en y
. Al cambiar el valor de x
, no afecta al valor almacenado en y
.
Por otro lado, la asignación por referencia significa que cuando se asigna un objeto a una variable, se le da una referencia a la ubicación de memoria del objeto en lugar de una copia del objeto. Por ejemplo:
let obj1 = {a: 1, b: 2}; let obj2 = obj1; obj1.a = 10; console.log(obj1.a); // 10 console.log(obj2.a); // 10
Aquí, cuando se asigna el objeto obj1
a obj2
, se almacena una referencia a la ubicación de memoria del objeto en obj2
. Al cambiar el valor de obj1.a
a 10
, el cambio también se refleja en obj2.a
porque apuntan a la misma ubicación de memoria.
En JavaScript, los tipos de datos primitivos (números, strings, booleanos, etc) se pasan por valor y los objetos (arrays, funciones y objetos) se pasan por referencia.
Es importante tener en cuenta que cuando trabajas con objetos, un cambio realizado en el objeto se reflejará en todas las variables que lo referencian.
Sentencias lógicas
En JavaScript, las sentencias lógicas se utilizan para tomar decisiones y controlar el flujo de un programa.
if
La sentencia lógica más básica es la sentencia if, que ejecuta un bloque de código si una cierta condición es verdadera. Por ejemplo:
let x = 5; if (x > 0) { console.log("x es positivo"); }
if-else
La sentencia if-else es similar a la sentencia if, pero también permite especificar un bloque de código para ejecutar si la condición es falsa. Por ejemplo:
let x = 0; if (x > 0) { console.log("x es positivo"); } else { console.log("x es no positivo"); }
if-else-if-else
La sentencia if-else-if-else permite encadenar varias condiciones juntas y ejecutar diferentes códigos dependiendo de la condición que es verdadera. Por ejemplo:
let x = 5; if (x > 0) { console.log("x es positivo"); } else if (x < 0) { console.log("x es negativo"); } else { console.log("x es cero"); }
switch
La sentencia switch es similar a la sentencia if-else if-else, pero se utiliza cuando hay un gran número de condiciones que deben ser probadas. La sentencia switch prueba el valor de una variable contra varios casos y ejecuta el código asociado al caso que coincide. Por ejemplo:
let day = "Monday"; switch (day) { case "Monday": console.log("Today is Monday"); break; case "Tuesday": console.log("Today is Tuesday"); break; case "Wednesday": console.log("Today is Wednesday"); break; case "Thursday": console.log("Today is Thursday"); break; case "Friday": console.log("Today is Friday"); break; case "Saturday": console.log("Today is Saturday"); break; case "Sunday": console.log("Today is Sunday"); break; default: console.log("Invalid day"); }
En este ejemplo, a la variable día se le asigna un string. La declaración de switch
prueba el valor de día contra múltiples casos y ejecuta el código asociado con el caso coincidente. Si el valor de día no coincide con ninguno de los casos, se ejecuta el código en el bloque predeterminado.
Además, la instrucción break
se usa para salir de la instrucción switch
y evitar que el código se ejecute en el siguiente caso.
En lugar de utilizar la sentencia break
en una sentencia switch
, también es posible utilizar la sentencia return
. La sentencia return
se utiliza para salir de una función y devolver un valor al código que la llama, mientras que la sentencia break
se utiliza para salir de un bucle o una sentencia switch
.
Aquí hay un ejemplo de una sentencia switch
en donde se utiliza la sentencia return
en lugar de la sentencia break
:
function getDay(day) { switch (day) { case "Monday": return "Today is Monday"; case "Tuesday": return "Today is Tuesday"; case "Wednesday": return "Today is Wednesday"; case "Thursday": return "Today is Thursday"; case "Friday": return "Today is Friday"; case "Saturday": return "Today is Saturday"; case "Sunday": return "Today is Sunday"; default: return "Invalid day"; } } console.log(getDay("Monday")) // Today is Monday
Es importante tener en cuenta que si usa la declaración de retorno, switch
saldrá de la función, por lo que si desea usar esta función, debe asegurarse de que la función ya no se use.
La instrucción return
detiene la ejecución de la función y devuelve un valor al código de llamada, mientras que la instrucción break
detiene la ejecución de un bucle o una instrucción switch
pero no devuelve ningún valor.