0% encontró este documento útil (0 votos)
11 vistas123 páginas

Guía Completa de JavaScript Vol. I

El documento es un manual completo sobre JavaScript, que abarca desde su introducción y comparación con otros lenguajes, hasta conceptos avanzados como ECMAScript y manipulación del DOM. Se detalla la sintaxis, tipos de datos, operadores, control de flujo, funciones y más, proporcionando herramientas útiles y recursos adicionales para el aprendizaje. Además, se menciona la evolución del lenguaje y su aplicación en diversas áreas más allá del desarrollo web.

Cargado por

vecaf70542
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
11 vistas123 páginas

Guía Completa de JavaScript Vol. I

El documento es un manual completo sobre JavaScript, que abarca desde su introducción y comparación con otros lenguajes, hasta conceptos avanzados como ECMAScript y manipulación del DOM. Se detalla la sintaxis, tipos de datos, operadores, control de flujo, funciones y más, proporcionando herramientas útiles y recursos adicionales para el aprendizaje. Además, se menciona la evolución del lenguaje y su aplicación en diversas áreas más allá del desarrollo web.

Cargado por

vecaf70542
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

JAVASCRIPT DEFINITIVO

VOL. I
Ariel Fuggini

Copyright © 2020 Ariel Fuggini

[Link]

ISBN: 978-1-64921-207-8
ÍNDICE
Introducción
¿Por qué JavaScript?
JavaScript vs. Otros Lenguajes
El Estándar ECMAScript
Requerimientos Previos
Herramientas Útiles
Herramientas Adicionales

Terminología y Sintaxis
Literales
Expresiones y Sentencias
Uso de Punto y Coma
Comentarios

Tipos de Datos
Primitivos
Características de los Tipos Primitivos
Objetos

Operadores
Operadores aritméticos
Operadores Relacionales
Operadores de Comparación
Operadores de asignación
Operadores Lógicos
Operador Condicional Ternario
Operadores Unarios
Operador Coma

Variables
¡No es una caja!
Asignación e Igualdad
Tipado en JavaScript
Conocer el Tipo de Valor
Ámbito de las Variables (Scope)
Nombrar Variables

Control de Flujo
Sentencia de bloque
Sentencia condicional
Sentencias de iteración
Sentencia switch
Sentencia break
Sentencia continue

Funciones
Parámetros y Argumentos

Booleanos
Valores Truthy y Falsy

Números
Number()
Métodos de Number
NaN
Infinity
Math

Strings
String()
Propiedades y Métodos de String

Objetos
Literales de Objeto
Objetos anidados
Métodos de Objeto
Objetos Globales o Nativos
¿Todo en JavaScript son Objetos?

Arrays
Uso Práctico de Arrays
Métodos de Array

Coerción
Coerción Implícita
Coerción Explícita

Temporizadores
setTimeout()
setInterval()

Manipulando el DOM
Selectores
Insertando Contenido
Crear Nuevos Elementos
Manipulando Atributos
Manipulando Clases

Eventos del DOM


Observando Eventos
Controlador de Evento
Evento
Propagación del Evento
Dejar de Observar Eventos

ECMAScript 2015
let y const
Función Flecha
Plantillas de Cadena de Texto
Propiedades Abreviadas de Objeto
Desestructuración
Operador de Propagación
Parámetro Resto
Parámetros por Defecto

Sobre el Autor
INTRODUCCIÓN

¿Por qué JavaScript?


JavaScript es el lenguaje de programación fundamental en el ámbito de la web. Es ideal para
aquellos que desean comenzar a programar por primera vez, y no tienen ninguna experiencia
previa, dado que se puede comenzar a trabajar con él directamente en el navegador web, sin
necesidad de instalar entornos de desarrollo ni herramientas complejas, como sucede con
otros lenguajes.

Tiene la característica de ser mucho menos estricto que otros lenguajes, y esto lo hace más
amigable con quienes lo adopten como su primer lenguaje de programación, debido a que
posee mecanismos internos con los que permite que un programa funcione en casos en los
que otros lenguajes arrojarían errores.

Por otra parte, cada vez más sitios web hacen uso extensivo de JavaScript, y ya no solamente
para agregarle detalles atractivos. En los últimos años las plataformas web pasaron a delegar
en el navegador y en JavaScript muchas de las tareas que antes sucedían del lado del
servidor. Por lo cual hoy en día los sitios web están cada vez más basados en JavaScript, y
desarrollando funcionalidades más complejas en el front-end.

JavaScript comenzó siendo un lenguaje orientado a la web, y por muchos años el navegador
fue su único contexto posible. Sin embargo, hoy en día se puede utilizar JavaScript para
proyectos que van mas allá de los sitios web, como pueden ser aplicaciones móviles,
aplicaciones de escritorio, servicios web, APIs, infraestructuras de back-end, juegos, IoT, etc.

Por lo tanto, conocer JavaScript a fondo nos va a abrir una infinidad de posibilidades en los
relacionado no solo al desarrollo web, sino al mundo del desarrollo de software en general.

JavaScript vs. Otros Lenguajes


JavaScript posee algunos elementos, características e implementaciones que difieren
sensiblemente de las de otros lenguajes. Como lector, si ya has trabajado con otros lenguajes
de programación, te propongo mantener una mente abierta a la hora de incorporar los
conceptos en este libro, dejando de lado los preconceptos que puedas tener. Y de esta forma,
permitirte entrar en el mundo de este nuevo lenguaje, que por lo demás, no tiene nada de
azaroso ni excéntrico, como se suele pensar, sino que esta basado, como el resto de los
lenguajes, en reglas establecidas por un estándar.

El Estándar ECMAScript
ECMAScript es una especificación de lenguaje de programación en la que se basa JavaScript.
La mayoría de navegadores web incluyen una implementación propia del estándar
ECMAScript para interpretar JavaScript. Por ejemplo, Google desarrolló su propio intérprete
de JavaScript para Chrome, llamado V8, que es también el motor de [Link]. Firefox, por su
parte, hizo lo propio creando SpiderMonkey. Y JavaScriptCore es la versión creada y utilizada
en Safari.

Las versiones vigentes de ECMAScript que existen al momento de escribir esto son:

5ta Edición
6ta Edición - ECMAScript 2015
7ma Edición - ECMAScript 2016
8va Edición - ECMAScript 2017
9na Edición - ECMAScript 2018
10ma Edición - ECMAScript 2019

A lo largo de este libro hago referencia en diferentes momentos a ECMAScript, a veces


también abreviado como ES5, ES6, ES2015, etc. Los ejemplos de código que utilizo se basan
mayormente en ECMAScript 5, con la intención de trazar una línea más clara entre lo que
corresponde a cada versión estándar. Y además, para reforzar la idea de que las
características que introduce cada nueva versión no llegan para reemplazar a las anteriores,
sino a complementarlas, a agregar nuevas posibilidades técnicas y semánticas al lenguaje.

No obstante, dedico un capítulo completo exclusivamente a las novedades más destacadas de


ECMAScript 2015. En futuros volúmenes de esta colección me dedicaré a profundizar aún
más sobre características más modernas del estándar.

Requerimientos Previos
Para comprender este libro no hace falta tener conocimientos previos en programación. Es
recomendable contar con alguna experiencia básica en HTML y CSS, y tener alguna práctica
mínima en la creación de páginas web con estos lenguajes. De esta forma, contarás con las
herramientas básicas para comenzar a crear código, y además podrás comprender mejor la
interacción de JavaScript con documentos web y lo que llamamos el DOM.

Herramientas Útiles
Para comenzar a crear código JavaScript podemos utilizar diferentes herramientas. La
principal sería un editor de código. Uno de los más populares en el ámbito del desarrollo
web, y que personalmente utilizo hoy en día es Visual Studio Code.

Para probar los ejemplos de este libro, así como cualquier fragmentos de código JavaScript
mientras aprendes el lenguaje, te recomiendo tener a mano el navegador Google Chrome, y
utilizar la herramienta de desarrollo o Developer Tools, también conocida como la consola, a
la que puedes acceder presionando CTRL + CMD + i en MacOS, o CTRL + SHIFT + i en
Windows.
En algunas ocasiones, ciertos fragmentos de código no devolverán un valor en la consola.
Para esos casos te recomiendo una herramienta llamada RunJS que nos permite evaluar
cualquier expresión de JavaScript en tiempo real para ver su resultado de forma aun más ágil.

Por último, muy buenas existen herramientas online para ejecutar nuestro código. Algunas
de ellas son:

CodePen
CodeSandbox
JSBin
StaticBlitz

Herramientas Adicionales
Para obtener recursos adicionales y facilitar tu aprendizaje, el libro cuenta con un
repositorio en Github con material que voy actualizando periódicamente. No es necesario
contar con una cuenta en Github, pero si no tienes una te recomiendo crearla ya que te será
muy útil.
TERMINOLOGÍA Y SINTAXIS

Literales
Un literal es un valor exacto, representado por una sintaxis específica. En otras palabras, la
forma de escribir literalmente un valor.

1024 // literal de number


"Hola mundo" // literal de string
[0, 2, 4] // literal de array
{ clave: valor } // literal de object
true // literal de boolean

En contraste, un valor no es literal cuando lo creamos por medio de constructos como


pueden ser funciones o clases.

Number(1024)
String("Hola mundo")
Object({ clave: valor })o
Array(0, 2, 4)
Boolean(true)

Expresiones y Sentencias
Una expresión (en inglés expression) es una unidad de código que JavaScript evalúa, y
devuelve a partir de ella un valor único.

Estas son algunas de las expresiones primarias de JavaScript:


2.14
true
undefined
this
function
class
/[a-z0-9]/g // expresión regular
i // variable
4 / 2 // expresión aritmética
"Hola" + " mundo" // expresión de string
x && y // expresión lógica
function () {} // expresión de declaración de función
new Object() // expresión de declaración de objeto

Una sentencia (en inglés statement) es una unidad más compleja de código. Puede estar
compuesta por una o más líneas, y contener múltiples expresiones.

// sentencias de declaración
var x = 0;
let y = true;
const z = "";

// sentencia condicional
if (condicion) {
// bloque de código
}

// sentencia de iteración
while (condicion) {
// bloque de código
}

return valor; // sentencia return

Para finalizar una sentencia y separarla del resto se utiliza el punto y coma (;).

Uso de Punto y Coma


De acuerdo con el estándar ECMAScript, es recomendable finalizar cada línea de nuestro
código JavaScript con punto y coma (;).
Sin embargo, esto no es estrictamente necesario en JavaScript, y el código funciona igual sin
ellos. Y es que JavaScript, en la mayoría de los casos, los agrega internamente de forma
automática cuando es requerido.

Personalmente tiendo a no utilizar punto y coma en mi código, excepto que trabaje sobre
código existente que ya lo usa. Esto es una decisión personal, ya que considero que el código
se ve más limpio de esta forma.

Sin embargo, mientras estés en etapa de aprendizaje, te recomiendo utilizar punto y coma
en todos los casos para evitar errores en tu código.

Comentarios
En JavaScript podemos utilizar una sintaxis especial para escribir comentarios entrelazados
con nuestro código, sin que afecten la ejecución normal del mismo.

Los comentarios son útiles para colocar notas sobre la intención de un determinado bloque
de código o para escribir primero nuestras ideas y luego transformarlas una a una en código,
entre otros usos posibles.

En los ejemplos de código de este libro aparecerán muchas veces comentarios que
representan el resultado de una expresión de JavaScript, o simplemente alguna nota sobre el
código mismo.

// Doble barra para comentarios de una línea

/*
Barra y asterísco para comentarios
que ocupan múltiples líneas.
*/

/***
* Puedes crear cualquier otra variante
* de los dos anteriores para generar
* comentarios con mejor estilo visual.
*/
TIPOS DE DATOS
En JavaScript existen dos categorías de datos: los primitivos y los objetos.

Primitivos
Los tipos primitivos son los tipos de datos más básicos de JavaScript. Al día de hoy, el
lenguaje cuenta oficialmente con 6 tipos primitivos:

Number
String
Boolean
Null
Undefined
Symbol

Number

El tipo Number abarca todos los datos de tipo numérico. Pueden ser números enteros o
decimales, como también otros tipos de valores numéricos como hexadecimales, binarios, y
octales.

256 // entero
3.14 // decimal
1e5 // notación de exponenciación (100000)
1e-5 // notación de exponenciación (0.00001)
0644 // octal (anteponiendo 0) (420)
0o10 // octal (anteponiendo 0o) (8)
0b1000 // binario (anteponiendo 0b) (8)
0xFF // hexadecimal (255)

String

El tipo de dato String nos permite almacenar y manipular cadenas de texto.

Para crear lo que llamamos un literal de string, simplemente encerramos nuestra cadena de
caracteres entre comillas dobles (") o comillas simples (') (el resultado es el mismo, esta
elección es simplemente una cuestión de preferencia). Y a partir de ECMAScript 2015,
también podemos definirlas utilizando tildes invertidas (`).
"Esto es un string"
"Esto también es un string"
`Esto es un string a partir de ES2015`

Boolean

El tipo Boolean o booleano tiene dos únicos valores posibles: true o false.

true
false

Null

El tipo Null tiene un único valor posible, null. Este representa la ausencia intencional de
valor, es decir, para indicar que un valor es nulo o está vacío.

null

Si bien la especificación de ECMAScript indica que corresponde usarlo en contextos en los


cuales el valor esperado es un objeto, en la práctica se utiliza para indicar la ausencia de
cualquier tipo de valor, incluídos los valores primitivos.

Undefined

El tipo Undefined también posee un único valor, undefined.

Similar a null, representa la ausencia de un valor. Sin embargo, la diferencia está en su


intención. Mientras que null representa un valor intencionalmente definido como nulo,
undefined es un valor no definido en un determinado momento, algo así como a la espera de
un valor.

undefined

Cuando en JavaScript declaramos una variable sin asignarle un valor inicial, se le asigna
automáticamente el valor undefined.
var x;

x; // → undefined

Symbol

Symbol es un tipo de dato que aparece en ES2015, y se utiliza principalmente para crear
referencias únicas llamadas símbolos para identificar propiedades de objetos.

Symbol()
Symbol("descripcion")

Por ser un tipo de dato poco frecuente no profundizaremos sobre su uso en este libro.

Llegando en ES2021: BigInt

BigInt aparece en ECMAScript 2021, que aún no es oficial al momento de escribir este libro.
Por lo tanto es el más nuevo de los tipos primitivos.

Fue creado para trabajar con números enteros más grandes de los que soporta el tipo
Number.

84920323940298340n

// o bien

BigInt(84920323940298340)

Al igual que Symbol, dado que BigInt es un tipo de dato nuevo y aun casi no utilizado, no
ahondaremos en él.

Características de los Tipos Primitivos


Los tipos primitivos son datos de bajo nivel, es decir, están más cerca de los ceros y unos.
Eso, entre otras cosas, los hace más rápidos de procesar.

Además, son inmutables, es decir, no pueden ser modificados. Pueden ser reemplazados por
otros valores luego de ser asignados a una variable, como veremos más adelante, pero no
pueden ser alterados en sí mismos. Son valores de sólo lectura.
Para comprender mejor los tipos primitivos, te voy a proponer que de ahora en más,
pensemos en ellos como valores que existen antes de que los nombremos, en una especie
de universo paralelo al que podemos llamar universo primitivo.

Entonces, tanto null, undefined, true, false, 3.14, y “tres tristes tigres”, así
como todos los números y cadenas de caracteres que podamos imaginar, habitan este
universo primitivo, y nosotros simplemente los referenciamos cuando los necesitamos.

Esto cobrará aún más sentido cuando hablemos sobre Variables.

“Universo Primitivo”

Objetos
La otra categoría de estructuras de datos en JavaScript son los objetos. Un objeto es un
constructo, una estructuras más complejas que un primitivo. Podríamos definirlo como una
colecciones de propiedades.

En JavaScript es posible crear nuestros propios objetos. Por ejemplo, un literal de objeto
consiste en una serie de propiedades y valores, separados por comas, y encerrados entre
llaves.

var automovil = {
marca: "Audi",
año: 2020,
valor: null,
caracteristicas: { abs: true }
}

JavaScript nos provee también de una serie de objetos globales o nativos, que nos son
útiles para diferentes tareas. Por ejemplo, el objeto Date nos permite trabajar con fechas y
datos temporales, o el objeto Math, que nos sirve para realizar diversas operaciones
matemáticas y numéricas complejas.

// método de redondeo
[Link](3.1415) // → 3

// crea un objeto fecha


new Date(2020, 3, 1)
// → Wed Apr 01 2020 00:00:00...

JavaScript cuenta además con dos subtipos de objetos que poseen características distintivas:
el array y la función.

Array

Un array, también conocido en español como Matriz o Arreglo, es una colección de


elementos ordenados e indexados, es decir, ordenados con un índice numérico.

// array de strings
["lunes", "martes", "miercoles", "jueves", "viernes"]

// array numérico
[1, 1, 2, 3, 5, 8]

// array mixto
[26, true, "js", new Date(), {}]

Función

Por su parte, una función es un tipo de objeto que posee la particularidad de que, al ser
declarado, no se ejecuta inmediatamente, sino que se guarda en memoria para ser invocado
más tarde, una o más veces.

Existen diferentes formas para declarar una función:


function miPrimerFuncion () {
return "Hola mundo";
}

// o bien

var miPrimeraFuncion = function () {


return "Hola mundo";
}

// o bien a partir de ES2015

const miPrimeraFuncion = () => {


return "Hola mundo";
}

// invocamos a la función
miPrimerFuncion() // →"Hola mundo"
OPERADORES
Ya conocemos los tipos de datos que podemos manipular en JavaScript. Lo siguiente que
vamos a necesitar saber es qué hacer cosas con esos datos.

Para esto vamos a necesitar conocer los diferentes operadores que nos van a permitir
precisamente realizar todo tipo de operaciones sobre los datos para conocerlos, compararlos,
modificarlos y crear nuevos.

Operadores aritméticos

Suma (+)

3 + 4 // →7

El operador + también puede concatenar strings.

"Hola" + " " + "mundo" // →"Hola mundo"

Resta (-)

5 - 2 // →3

Multiplicación (*)

6 * 4 // →24

División (/)

8 / 2 // →4

Módulo (%)
También llamado resto, Devuelve el resto de la división de dos operandos.

9 % 4 // →1

Incremento (++)

Incrementa en una unidad al operando. Si es usado antes del operando (++x) devuelve el
valor del operando después de añadirle 1, y si se usa después del operando (x++) devuelve el
valor de este antes de añadirle 1.

var x = 0;
var y = ++x; // incrementa x a 1, luego devuelve 1
var z = x++; // devuelve 1, luego incrementa x a 2
x; // → 2
y; // → 1
z; // → 1

Decremento (–)

Resta una unidad al operando. La posición con respecto al operando tiene el mismo
comportamiento que el operador de incremento.

var x = 2;
var y = --x; // decrementa x a 1, luego devuelve 1
var z = x--; // devuelve 1, luego decrementa x a 0
x; // → 0
y; // → 1
z; // → 1

Negación Unaria (-)

Al anteponer el signo -, JavaScript intenta convertir a número al operando y devolver su


forma negativa.

-"3" // → -3
-true // → -1
Unario Positivo (+)

Al anteponer el signo -, JavaScript intenta convertir a número al operando.

+"3" // → 3
+true // → 1

Exponenciación (**)

x ** y devuelve x a la potencia y. Introducido en ES2016.

2 ** 3 // → 8

Operadores Relacionales
Los operadores relacionales comparan sus operandos y retorna un booleano como
resultado.

in

propiedad in objeto

Devuelve true si la propiedad especificada se encuentra en el objeto.

"PI" in Math; // → true


"length" in []; // → true

var automovil = { marca: "Ford" };


"marca" in automovil; // → true
"modelo" in automovil; // → false

También se utiliza en el bucle de tipo for...in.


var persona = { edad: 21, sexo: "Masculino", ojos:
"Marrones" };

for (atributo in persona) {


[Link](atributo + "->" + persona[atributo]);
}

// → edad -> 21
// → sexo -> "Masculino"
// → ojos -> "Marrones"

instanceof

objeto instanceof TipoDeObjeto

Devuelve true si el objeto especificado como primer operando es del tipo especificado en el
segundo operando.

[1, 2, 3] instanceof Array; // → true


({ a: 1 }) instanceof Object; // → true

Operadores de Comparación
Los operadores de comparación también pertenecen a la categoría de operadores
relacionales.

Igualdad (==)

x == y

Devuelve true si ambos operandos son iguales.

"Ariel" == "Ariel" // → true


2 == 2 // → true
null == null // → true
Dado el funcionamiento de este operador, es importante tener en cuenta estos posibles
resultados:

0 == false // → true
2 == "2" // → true
"" == 0 // → true
false == "" // → true
null == undefined // → true

Esto no es un error, sino que es debido al algoritmo que utiliza el operador internamente
para realizar la comparación. Este tema lo abordo con más detalle en el capítulo sobre
coerción.

Igualdad estricta (===)

x === y

Devuelve true si los operandos son del mismo tipo y valor.

"Ariel" === "Ariel" // → true


2 === 2 // → true
null === null // → true

0 === false // → false


2 === "2" // → false
"" === 0 // → false
false === "" // → false

Desigualdad (!=)

x != y

Devuelve true si ambos operandos no son iguales.


"Ariel" != "Fuggini" // → true
2 != 3 // → true
null != 0 // → true

Tener en cuenta también que:

0 != false // → false
2 != "2" // → false
"" != 0 // → false
false != "" // → false
null != undefined // → false

Desigualdad estricta (!==)

x !== y

Devuelve true si los operandos no son del mismo tipo y/o valor.

"Ariel" !== "Fuggini" // → true


2 !== 3 // → true
null !== undefined // → true

0 !== false // → true


2 !== "2" // → true
"" !== 0 // → true
false !== "" // → true

Mayor que (>)

x > y

Devuelve true si el operando de la izquierda es mayor que el operando de la derecha.

Mayor o igual que (>=)


x >= y

Devuelve true si el operando de la izquierda es mayor o igual que el operando de la derecha.

Menor que (<)

x < y

Devuelve true si el operando de la izquierda es menor que el operando de la derecha.

Menor o igual que (<=)

x <= y

Devuelve true si el operando de la izquierda es menor o igual que el operando de la derecha.

Operadores de asignación

Asignación (=)

x = y

Con x = y estamos diciendo que la variable x es igual al valor de y.

x = "JS";
y = 43;
z = y;

Asignación de adición (+=)

x += y

Equivale a x = x + y.
Asignación de sustracción (-=)

x -= y

Equivale a x = x - y.

Asignación de multiplicación (*=)

x *= y

Equivale a x = x * y.

Asignación de división (/=)

x /= y

Equivale a x = x / y.

Asignación de resto (%=)

x %= y

Equivale a x = x % y.

Asignación de exponenciación (**=)

x **= y

Equivale a x = x ** y. Introducido en ES2016.

Operadores Lógicos

AND (&&)
El valor producido por && no es necesariamente de tipo boolean, sino que es siempre el valor
de uno de sus dos operandos.

x && y

Si x es un valor falso (falsy), devuelve x. Si no, devuelve y.

true && true; // → true


true && false; // → false
false && true; // → false
"Perro" && "Gato"; // → "Gato"

var debug = true;


debug && [Link]("Debug ON"); // → "Debug ON"

OR (||)

El valor producido por || no es necesariamente de tipo boolean, sino que es siempre el valor
de uno de sus dos operandos.

x || y

Si x es un valor verdadero (truthy), devuelve x. Si no, devuelve y.

true || true; // → true


true || false; // → true
false || true; // → true
"Perro" || "Gato"; // → "Perro"

var x = false;
x || [Link]("Dev"); // → "Dev"

NOT (!)

!x
Devuelve un booleano contrario al valor del operando. Si el operando es verdadero, devuelve
false. De lo contrario, devuelve true.

!true // → false
!false // → true
!"Perro" // → false
!0 // → true
!1 // → false
!undefined // → true
!null // → true
![] // → false
!{} // → false

Se suele utilizar también como !!, que no es más que dos negaciones consecutivas, logrando
el resultado exactamente opuesto, es decir, convertir el operando a su versión booleana.

!!true // → true
!!false // → false
!!"Perro" // → true
!!0 // → false
!!1 // → true
!!undefined // → false
!!null // → false
!![] // → true
!!{} // → true

Operador Condicional Ternario

condicion ? valor1 : valor2

Si la condición es verdadera, devuelve valor1, de lo contrario devuelve valor2.

function obtenerEstado (edad) {


return (edad < 18) ? "menor" : "adulto";
}

obtenerEstado(14); // → "menor"
obtenerEstado(32); // → "adulto"
Operadores Unarios

typeof

typeof operando
typeof (operando)

Devuelve una string indicando el tipo del operando evaluado. Los paréntesis son opcionales.

El resultado de la operación es siempre un string.

typeof "Hola mundo" // → "string"


typeof 39548 // → "number"
typeof true // → "boolean"
typeof false // → "boolean"
typeof {} // → "object"
typeof [] // → "object"
typeof null // → "object"
typeof Date // → "object"
typeof [Link] // → "function"
typeof BigInt(23) // → "bigint"
typeof Symbol() // → "symbol"
typeof noExiste // → "undefined"

void

void expresion
void (expresion)

Previene que una expresión devuelva un valor. Los paréntesis son opcionales.

Su uso es poco frecuente, y se utiliza muchas veces para ejecutar una expresión en JavaScript
desde un link HTML sin provocar efectos secundarios.
<a href="javascript:void(0)">Este link no hace nada</a>

<a href="javascript:void(unaFuncion())">Este link ejecuta


unaFuncion()</a>

delete

delete [Link]
delete array[indice]

Elimina una propiedad de un objeto o un elemento de un array. Como resultado devuelve un


booleano indicando si la operación se realizó con éxito.

var miObjeto = { x: 1, y: 2 };
var miArray = ["gato", "perro", "conejo"];

delete miObjeto.x;
// → true
// (la propiedad x se ha eliminado)

delete miObjeto;
// → false
// (no puede eliminar un objeto)

delete [Link];
// → false
// (no puede eliminar propiedades predefinidas de un objeto
global)

delete miArray[2];
// → true
// (el valor "conejo" fue eliminado)

miArray[2]; // → undefined

Operador Coma
El operador coma (,) evalúa dos operandos y retorna el valor del último.
Este operador se utiliza principalmente dentro de un bucle for, permitiendo declarar
múltiples variables y evaluarlas en cada iteración.

for (var i = 0, j = 10; i < j; i++, j--) {


[Link](array[i][j]);
}

Además, también se puede utilizar para declarar múltiples variables en una misma
expresión.

var a, b, c;

var d = 0,
f = true,
f = "Usuario";
VARIABLES
Las variables son un componente importante de muchos de los lenguajes de programación,
incluido JavaScript. Una variable es esencialmente una referencia, que nos permite
etiquetar un valor y guardarlo en la memoria para utilizarlo más tarde.

Para declarar una variable, lo hacemos utilizando la palabra clave var, seguida de un
nombre que la identifique.

var miPrimerVariable = "Hola mundo";

Podemos almacenar cualquier tipo de dato en una variable.

var mascota = "Perro";


var patas = 4;
var ladra = true;
var comidasFavoritas = ["Croquetas", "Filetes"];

Las variables nos sirven para reutilizar valores, realizar operaciones sobre ellos, pasarlos
como argumentos a funciones, entre otros.

var valor1 = 3;
var valor2 = 2;

// operación de multiplicación
valor1 * valor2; // → 6

// como argumentos de función


[Link](valor1, valor2);

¡No es una caja!


Muchas veces leyendo en internet vamos a encontrar definiciones de variable
representándolas como cajas que contienen un valor. Sin embargo, esta explicación no nos
ayuda a hacernos un modelo mental correcto de cómo funciona una variable.

En lugar de eso, te propongo imaginar que declarar una variable es como crear una etiqueta,
y que al asignarle un valor, estamos tendiendo un hilo que conecta esta etiqueta con el valor.
var mascota = "Perro";

Asignación e Igualdad
Dicho esto, vale la pena también hacer una aclaración adicional:

Es frecuente que se confundan las variable con valores. Una variable no es un valor,
sino que hace referencia a un valor.

Siguiendo con el ejemplo anterior, declaramos ahora una nueva variable animal, y le
asignamos también el valor "Perro".

var mascota = "Perro";


var animal = "Perro";

Cuando hablamos de los tipos primitivos, dijimos que ellos existen antes que los
nombremos, en un universo primitivo, y que nosotros simplemente los evocamos o
referenciamos. Entonces, siguiendo esta lógica, como el string "Perro" ya existe, las dos
variables mascota y animal van a estar conectadas al mismo valor.

Esto es exactamente igual a declarar la nueva variable de la siguiente manera:


var mascota = "Perro";
var animal = mascota;

Al igualar animal a mascota, lo que estamos haciendo es unir ambas etiquetas animal y
mascota al mismo valor primitivo.

En ambos ejemplos, las dos variables referencian al string "Perro", y por lo tanto al
compararlas con el operador de igualdad estricta nos arrojará true.

mascota === animal; // → true

Y es que ambas variables son ahora equivalentes al literal de string "Perro". Y "Perro" es
siempre igual a "Perro".

"Perro" === "Perro"; // → true

Supongamos ahora que más adelante en nuestro código queremos reemplazar el valor de
mascota por el string "Gato".

var mascota = "Perro";


var animal = mascota;

// luego...

mascota = "Gato";

Te propongo tomarte unos minutos y reflexionar: ¿cuál es ahora el valor de la variable


animal?

animal; // ???

La respuesta es la siguiente: según nuestro modelo de etiquetas, al modificar el valor de


mascota, estamos desconectando el hilo que la une al valor "Perro" y reconectándolo con
el valor "Gato".

Sin embargo, la variable animal sigue conectada al string "Perro", y por lo tanto ese
seguirá siendo su valor.
var mascota = "Perro";
var animal = mascota;

mascota = "Gato";

animal; // → "Perro"

En este ejemplo podemos ver claramente por qué, si pensáramos las variables como cajas,
podríamos creer que animal contiene a mascota, y por lo tanto al modificar en valor de
mascota, estaríamos cambiando también el valor de animal, lo cual sería incorrecto.

Las variables se conectan con valores, y no con otras variables. Siempre de un lado del
hilo está la etiqueta, y del otro, el valor.

Veamos ahora un ejemplo utilizando objetos, en este caso arrays.

Declaramos una variable lista1 y le asignamos como valor un objeto array vacío. Luego
repetimos lo mismo con lista2.
var lista1 = [];
var lista2 = [];

¿Es igual el valor de estas dos variables?

Vamos a preguntarle a JavaScript:

lista1 === lista2; // → false

La comparación nos arroja false. ¿Por qué?

Cada vez que asignamos a una variable un literal de objeto con [] o {}, estamos creando en
ese instante un objeto nuevo.

Como resultado, lista1 y lista2 hacen referencia a dos objetos diferentes.

Es por eso que al intentar comparar objetos o arrays con el operador de igualdad, el resultado
será siempre false.

[] === []; // → false


{} === {}; // → false
["diferente"] === ["diferente"]; // → false
{ valor: 0 } === { valor: 0 }; // → false

Siguiendo con el ejemplo, insertamos ahora un string "x" en la posición 0 del array lista1.
var lista1 = [];
var lista2 = [];

lista1[0] = "x";

Con lo que ya sabemos, podemos tener la certeza de que, al ser arrays diferentes, al modificar
uno, no alteraremos el otro.

Fácil ¿verdad?

Ahora veamos que sucede con el siguiente código:

var lista1 = [];


var lista2 = [];

lista1[0] = "x";

lista2 = lista1;

lista2[0] = "y";

A partir del fragmento anterior ¿cuál sería la representación correcta? Tómate unos minutos
para refleccionarlo.
Vayamos paso a paso.

lista2 = lista1;

Al igualar lista2 a lista1, lo que estamos haciendo es equivalente a desconectar lista2


de un array, y reconectándola al otro, al mismo que lista1.

El array que antes estaba conectado a lista2 ahora quedó desconectado de toda variable, y
por lo tanto partir de ahora es inalcanzable, por lo que JavaScript lo va a eliminar para
liberar memoria, en un proceso llamado Garbage Collection.

Ahora, lista1 y lista2 están unidas (referencian) al mismo array, que a estas alturas
equivale a ["x"], y por lo tanto cualquier alteración o mutación en este array se reflejará en
ambas variables.

De manera que la respuesta correcta es la B. Al modificar el índice 0 de lista2, estamos


mutando el array al que ambas conectan.

lista2[0] = "y";

lista1; // → ["y"]
lista2; // → ["y"]
En este caso sí, al comparar ambas referencias, obtendremos un resultado positivo.

lista1 === lista2; // → true

Tipado en JavaScript
JavaScript es un lenguaje llamado de tipado dinámico. Esto quiere decir que, mientras en
otros lenguajes es necesario hacer explícito el tipo de variables al declararla (por ejemplo, si
es de tipo string, boolean, etc), en JavaScript las variables no tienen tipo, sino que el
tipo (en inglés type) es una característica del valor.

Es por eso que en JavaScript podemos asignarle a una variable un valor de cualquier tipo, por
ejemplo string, y más tarde reemplazarlo por otro, por ejemplo un number, sin provocar
ningún error.

Si bien el lenguaje nos brinda esta posibilidad, asignar a una variable diferentes tipos de
datos a lo largo de una misma aplicación puede generar inconsistencias y confusión si no
somos extremadamente cuidadosos y explícitos, por lo cual te recomiendo evitarlo siempre
que sea posible.

var a = "Ariel";
typeof a; // → "string"
a = 34;
typeof a; // → "number"
a = true;
typeof a; // → "boolean"
a = [];
typeof a; // → "object"
a = undefined;
typeof a; // → "undefined"
Conocer el Tipo de Valor
Para conocer el tipo de valor podemos utilizar el operador typeof, como ya vimos
ejemplificado anteriormente.

typeof "Hola mundo" // → "string"


typeof 39548 // → "number"
typeof true // → "boolean"
typeof false // → "boolean"
typeof {} // → "object"
typeof [] // → "object"
typeof null // → "object"
typeof Date // → "object"
typeof [Link] // → "function"
typeof BigInt(23) // → "bigint"
typeof Symbol() // → "symbol"
typeof noExiste // → "undefined"

En el caso de un array, typeof nos devuelve "object" porque, en rigor, un array es un tipo
de objeto. Para evitar confundirlo con cualquier otro tipo de objeto, podemos utilizar el
método [Link]().

var x = [1, 4, 6];


[Link](x); // → true

var y = ["enero", "febrero", "marzo"];


[Link](y); // → true

var z = { noEs: "un array" };


[Link](z); // → false

Por otra parte, null es en rigor un dato de tipo Null según la especificación de ECMAScript.
Sin embargo, typeof nos arroja que es un "object". Esto se debe a un bug que data de las
primeras versiones de JavaScript, y que se ha decidido deliberadamente no corregir, ya que
esto podría provocar otros bugs de forma masiva.

Por lo tanto, para saber si una variable es null, podemos utilizar el operador de igualdad
estricta ===:
var n = null;

n === null; // → true

Ámbito de las Variables (Scope)


Analicemos el siguiente código.

var a = 1;

function scope () {
a = 3;
var b = 4;

a; // → 3
b; // → 4
}

a; // → ?
b; // → ?

scope();

a; // → ?
b; // → ?

¿Qué valor poseen a y b antes y después de invocar la función scope()?

En JavaScript el ámbito de las variables declaradas con var lo define la función. Por lo tanto,
las variables tienen un alcance limitado al contexto de la función dentro de la cual son
declaradas, es decir, quedan inaccesibles fuera de ese ámbito o scope.

En el ejemplo, la primera vez que llamamos a a fuera de la función, esta preserva el valor con
el que fue declarada en la primera línea. Por lo tanto su valor es 1. b sin embargo no fue
declarada, y por lo tanto devuelve undefined.

Al invocar la función scope(), se les asigna un nuevo valor a a, y se declara una variable b.
Ámbas están ahora disponibles dentro del ámbito de la función.

¿Qué sucede con a y b fuera de la función después de invocar scope()?


a fue modificada y por lo tanto su valor es 3. Sin embargo, b sigue sin existir en el contexto
global (fuera de la función), y por lo tanto sigue siendo undefined.

A partir de ES2015, let y const nos permiten declarar variables que cuyo ámbito funciona
de manera diferente. Esto lo desarrollo en detalle en el capítulo sobre ECMAScript 2015.

Nombrar Variables
Al elegir el nombre de una variable debemos tener en cuenta ciertas reglas y limitaciones.

Los nombres de una variable sólo pueden contener letras, números, _, y $;


No pueden comenzar con un número;
Distinguen mayúsculas y minúsculas, es decir que x y X serán variables diferentes;
No se permite usar ciertas palabras reservadas de JavaScript, es decir las que poseen
un significado especial, como por ejemplo if, for, break, function, etc;
CONTROL DE FLUJO
El control de flujo (Control flow) es, en ciertos lenguajes de programación como en
JavaScript, el orden en que son ejecutadas las instrucciones en el código.

El código JavaScript se ejecuta, a grandes rasgos, en un orden líneal, desde la primera línea
de código hasta la última. Sin embargo, este orden se altera cuando el intérprete (el
navegador) encuentra un bloque de código que cambia el flujo.

A los bloques de código que tienen la capacidad de alterar el flujo de ejecución de nuestro
código JavaScript se les conoce como estructuras de control.

A continuación te explico las diferentes estructuras de control que existen en el lenguaje.

Sentencia de bloque
La sentencia de bloque es una estructuras sencilla, que se utiliza simplemente para agrupar
declaraciones, y no modifica el flujo de ejecución.

{
var mascota = "Perro";
[Link]("Mi mascota es " + mascota);
}

Sentencia condicional
La sentencia condicional se utilizan para ejecutar un bloque de código únicamente si se
cumple cierta condición.

// si una condición es verdadera...


if (condicion) {

// entonces ejecuta el código aquí dentro

Por ejemplo:
if (edad >= 18) {
[Link]("Eres mayor de edad");
} else {
[Link]("Eres menor de edad");
}

if (
diaDeLaSemana === "sabado"
|| diaDeLaSemana === "domingo"
) {
descansar();
} else if (diaDeLaSemana === "viernes") {
prepararseParaElFinDeSemana();
} else {
trabajar();
}

Sentencias de iteración
Las sentencias de iteración, también llamadas bucles o loops, se utilizan para ejecutar un
bloque de código de forma reiterativa, y basada en alguna condición.

JavaScript cuenta con varias estructuras de este tipo.

while

La sentencia while itera sobre un bloque de código continuamente mientras la condición


indicada sea verdadera.
var i = 5;

while (i > 0) {
[Link]("i es igual a " + i);
i--;
}

// → "i es igual a 5"


// → "i es igual a 4"
// → "i es igual a 3"
// → "i es igual a 2"
// → "i es igual a 1"

do … while

La sentencia do…while funciona igual que while, pero con la diferencia de que el bloque de
código se ejecuta al menos una vez, independientemente del valor de la condición.

El siguiente código obtiene el mismo resultado que while.

var i = 5;

do {
[Link]("i es igual a " + i);
i--;
} while (i > 0);

// → "i es igual a 5"


// → "i es igual a 4"
// → "i es igual a 3"
// → "i es igual a 2"
// → "i es igual a 1"

do {
[Link]("Me veras solo una vez");
} while (true === false);

// → "Me veras solo una vez"


for

La sentencia for recibe tres argumentos que determinan la forma de iteración del bloque de
código.

Una expresión inicial que se ejecuta una sola vez, antes de la primer iteración;
Una condición que debe cumplirse para ejecutar el bloque de código;
Una expresión final que se ejecuta al final de cada iteración;

Por lo tanto, el bucle va a iterar sobre el bloque de código tantas veces como se cumpla la
condición, y teniendo disponible dentro de su contexto los valores de las expresiones inicial
y final.

for (expresionInicial; condicion; expresionFinal) {


// código a ejecutar
}

for (var i = 1; i <= 5; i++) {


[Link]("vuelta " + i);
}

// → "vuelta 1"
// → "vuelta 2"
// → "vuelta 3"
// → "vuelta 4"
// → "vuelta 5"

Aunque no es su único uso, es común el uso del bucle for para iterar sobre arrays, escrito de
la siguiente forma:

var array = [1, 3, 5, 7, 9];

for (var i = 0; i < [Link]; i++) {


[Link]("El valor es: " + array[i]);
}

// → "El valor es: 1"


// → "El valor es: 3"
// → "El valor es: 5"
// → "El valor es: 7"
// → "El valor es: 9"
for … in

La sentencia for…in itera sobre los elementos de un objeto en un orden arbitrario,


ejecutando el bloque de código una vez por cada uno.

El valor a la izquierda de in representa el nombre de la propiedad del objeto correspondiente


a la iteración en curso.

var automovil = {
marca: "Audi",
modelo: "A1",
año: 2020
}

for (var dato in automovil) {


[Link](dato + " es " + automovil[dato]);
}

// → "marca es Audi"
// → "modelo es A1"
// → "año es 2020"

Sentencia switch
La sentencia switch evalúa una expresión, comparando su valor con otro valor llamado
case. Cuando los valores coinciden, se ejecuta el código comprendido desde el case hasta el
final del bloque switch, o hasta encontrar una sentencia break.

Si ninguno de los case coincide con la expresión evaluada, se buscará una sentencia
default, y si esta presente, se ejecutará el código que le sigue.
var ahora = new Date();

// obtiene el número de día


// de la semana, de 0 a 6
var diaDeLaSemana = [Link]();

switch (diaDeLaSemana) {
case 0:
[Link]("Domingo");
break;
case 1:
[Link]("Lunes");
break;
case 2:
[Link]("Martes");
break;
case 3:
[Link]("Miércoles");
break;
case 4:
[Link]("Jueves");
break;
case 5:
[Link]("Viernes");
break;
case 6:
[Link]("Sábado");
break;
default:
[Link]("Día inexistente");
}

Sentencia break
La sentencia break interrumpe abruptamente la ejecución de un bloque, sentencia de
iteración o sentencia switch.
// dado un bucle `for...in`
for (var x in objeto) {

// si se cumple cierta condición...


if (x === "modelo") {

// interrumpir el bucle `for`


break;
}
}

Sentencia continue
La sentencia continue interrumpe la iteración en curso, y hace que se continúe con la
siguiente.

var automovil = {
marca: "Audi",
modelo: "A1",
año: 2020
}

for (var dato in automovil) {


if (dato == "modelo") {
continue;
} else {
[Link](dato + " es " + automovil[dato]);
}
}

// → "marca es Audi"
// → "año es 2020"
FUNCIONES
Una función es un bloque de código capaz de realizar una o más tareas, y luego devolver un
valor como resultado.

En JavaScript, las funciones también son un tipo de objeto.

// declara una función `sumar`


// que retorna la operación 2 + 2
function sumar () {
return 2 + 2;
}

La sentencia return es la que indica qué valor devolverá la función. Es opcional, y cuando
no se especifica un valor de retorno, la función devuelve undefined.

El código dentro de una función es ejecutado una vez que la función es invocada, utilizando
su nombre de identificador seguido de ().

sumar(); // → 4

Este ejemplo nos muestra una función que suma 2 + 2, y nos retorna el resultado.

En la práctica, esto no sería muy util, ya que si quisiéramos por ejemplo realizar la operación
suma sobre otros valores, tendríamos que crear una nueva función para cada combinación
posible.

Para resolver esto, las funciones aceptan parámetros.

Parámetros y Argumentos
Para hacerla mas dinámicas, las funciones aceptan argumentos, que son valores que
podemos pasarle a la función al invocarla con los ().

Para determinar qué argumentos acepta una función, al momento de declararla le definimos
parámetros, entre los paréntesis y separados por ,:

function miFuncion (parametro1, parametro2, parametro3) {


// contenido de la función
}
Veamos cómo podría quedar nuestra función sumar() al agregarle parámetros:

function sumar (a, b) {


return a + b;
}

Los argumentos quedan disponibles como variables dentro del ámbito de la función. Ahora,
nuestra función sumar() recibe dos argumentos que serán los operandos de la suma, y por
lo tanto es mucho más versátil que su versión anterior. Por ejemplo:

sumar(4, 3); // → 7
sumar(100.51, 3.1415); // → 103.6515

Los términos parámetro y argumento suelen ser confundidos y utilizados


indistintamente, lo cual es un error. Recuerda que el parámetro es el nombre que
definimos dentro de los paréntesis al declarar la función, la etiqueta. Y el argumento
es el valor que recibe un parámetro al invocarse la función.

Una función puede definir 0 o más parámetros, y aceptar 0 o más argumentos. Además puede
no ser necesario pasarle a una función valores para todos sus parámetros, pero sí es
importante el orden en que se los pasemos, que debe corresponder con el orden establecido
al declarar la función.

También es posible pasarle argumentos a una función que no declarar ningún parámetro, ya
que los argumentos son accesibles dentro del ámbito de la función en el objeto arguments.

Por ejemplo, nuestra función sumar podría declararse sin parámetros de la siguiente
manera:

function sumar () {
return arguments[0] + arguments[1];
}

sumar(6, 3); // → 9
BOOLEANOS
Un boolean es un dato binario, es decir, tiene solo dos valores posibles, true y false.

El tipo booleano es util cuando en nuestro código necesitamos distinguir entre dos
posibilidades, por ejemplo:

verdadero / falso
prendido / apagado
si / no

Como vimos, ciertos operadores arrojan como resultado un valor booleano.

0 == "0" // → true
0 === 1 // → false
0 != "1" // → true
0 !== 1 // → true
0 < 1 // → true
0 >= 1 // → false
!0 // → true

Valores Truthy y Falsy


En los contextos en que un valor booleano es lo esperado, y se utiliza en su lugar un valor
que diferente tipo, JavaScript lo fuerza de manera implícita a comportarse como booleano.

Los valores convertibles a false se conocen como falsy o falsey, y son aquellos que cuando
se encuentran en un contexto de booleano, JavaScript los convierte a false:

0 (cero)
-0 (cero negativo)
0n (cero de tipo BigInt)
"" (comillas dobles vacías)
'' (comillas simples vacías)
`` (tildes invertidas vacías)
null
undefined
NaN

Entonces, si utilizaramos cualquiera de estos valores en un contexto de condicional, la


condición resultara falsa.
var resultado = [Link]("cero");
// → NaN

// por lo tanto resultado es falsy


if (resultado) {
[Link]("Esto nunca se mostrará");
}

Por consiguiente, el resto de los valores en JavaScript son convertibles a true, y se


consideran truthy.

Esto es posible gracias al mecanismo de coerción, al cual le dedicamos un capítulo más


adelante. Básicamente, cuando lo que se espera es un booleano, JavaScript fuerza el valor al
tipo boolean, en una operación equivalente a llamar la función global Boolean sobre él.

// todos los siguientes retornan `false`


Boolean(false)
Boolean(0)
Boolean(-0)
Boolean(0n)
Boolean("")
Boolean('')
Boolean(``)
Boolean(null)
Boolean(undefined)
Boolean(NaN)

// cualquier otro valor retorna `true`


Boolean(true)
Boolean([])
Boolean({})
Boolean('Hola mundo')
Boolean(new Date())
NÚMEROS
En JavaScript gran parte del trabajo con números es posible gracias a los operadores. Sin
embargo, también contamos con una serie de objetos y funciones con los cuales manipular
números.

Number()
La función global Number() nos permite crear valores de tipo number a partir de cualquier
valor.

Number(23) // → 23
Number(3.14) // → 3.14
Number("23") // → 23
Number("3.14") // → 3.14
Number(true) // → 1
Number(false) // → 0
Number(null) // → 0
Number(undefined) // → NaN
Number([]) // → 0
Number([0]) // → 0
Number([1]) // → 1
Number([2, 3, 4]) // → NaN
Number({}) // → NaN
Number({ a: 1, b: 2 }) // → NaN

Para conocer en mayor profundidad las posibilidades que nos da Number puedes visitar
este link.

Métodos de Number

parseInt()

El método global parseInt() recibe un string y lo convierte en un número entero. Es


también accesible como método del objeto global Number.

Si el valor no puede ser convertido, retorna NaN.


parseInt("10"); // → 10
parseInt("10.83"); // → 10
parseInt("10 20 30"); // → 10
[Link]("10 años"); // → 10
[Link]("Messi 10"); // → NaN

parseFloat()

El método global parseFloat() recibe un string y lo convierte en un número decimal o de


punto flotante. Es también accesible como método del objeto global Number.

Si el valor no puede ser convertido, retorna NaN.

parseFloat("3.14"); // → 3.14
parseFloat("314e-2"); // → 3.14
parseFloat("0.0314E+2"); // → 3.14
[Link]("3.14 es PI"); // → 3.14
[Link]("PI es 3.14"); // → NaN

toFixed()

El método toFixed() devuelve un string del número con la cantidad de decimales


especificada como parámetro.

var PI = 3.1415;
[Link](2); // → "3.14"
[Link](3); // → "3.141"
[Link](0); // → "3"
[Link](); // → "3"

NaN
NaN es una propiedad global de JavaScript. Comúnmente se dice que NaN no es un número,
ya que si nombre proviene de *Not-a-Number“* (No-Numero). Sin embargo, si verificamos
su valor mediante el operador typeof, veremos que en JavaScript, (por especificación del
estándar ECMAScript) NaN es un valor numérico:
typeof NaN // → "number"

Por lo tanto, es más apropiado considerar a NaN como un número, y más precisamente, un
número inválido.

Muchos métodos de JavaScript retornan NaN cuando no pueden parsear sus parámetros
como números válidos.

Number(23 + {}) // → NaN


parseInt(10 / 0) // → NaN
parseFloat(20 * "no soy numero") // → NaN
43 - "veinte" // → NaN

NaN nunca equivale a ningún otro número, incluido NaN.

NaN == NaN // → false


NaN === NaN // → false

Una de las formas en que podemos chequear si un valor es NaN es usando la función global
isNaN(), que devuelve un booleano según si el argumento que recibe es o no NaN.

isNaN(NaN) // → true
isNaN(1) // → false

Sin embargo, esta función también tiene ciertos corner cases, es decir casos en los que no
resulto como se esperaría:

isNaN() // → true
isNaN("Ariel") // → true
isNaN(undefined) // → true

Esto es debido a que los valores no numéricos que recibe isNaN() son coercionados al tipo
number antes de ser evaluados. Entonces, dado que cualquier string o undefined al ser
forzados a number devuelven NaN, isNaN(NaN) siempre devuelve true.
Number(undefined) // → NaN
Number("Ariel") // → NaN

// por lo tanto

isNaN(Number(undefined)) // → true
isNaN(Number("Ariel")) // → true

Tanto NaN como isNaN() también son accesibles como [Link] y [Link]().

var numeroInvalido = parseInt(2 / 0); // → NaN


[Link](numeroInvalido); // → true

[Link]([Link]); // → true

Infinity
Infinity es una propiedad global. En el navegador, las propiedades globales pertenecen al
objeto window. Por lo tanto también es posible referirnos a Infinity como
[Link].

Infinity se comporta como el infinito matemático: cualquier numero multiplicado por


Infinity da como resultado Infinity, mientras que dividir cualquier numero por
Infinity resulta 0.

6 * Infinity // → Infinity
8 / Infinity // → 0

También existe en su forma negativa: -Infinity.

Math
El objeto global Math cuenta con múltiples propiedades y métodos útiles para realizar
operaciones matemáticas. A continuación veremos algunos de los más destacados.

Para una referencia completa del objeto Math puedes visitar este link.
Math.E

Devuelve el valor matemático E.

Math.E // → 2.718281828459045

[Link]

Devuelve el valor matemático PI.

[Link] // → 3.141592653589793

[Link]()

Redondea un número hacia el entero más próximo.

[Link](3.14) // → 3
[Link](5.79) // → 6
[Link](7.5) // → 8

[Link]()

Redondea un número hacia arriba, hacia el entero más próximo.

[Link](82) // → 82
[Link](2.02) // → 3
[Link](4.001) // → 5
[Link](-4.001) // → -4

[Link]()

Redondea un número hacia abajo, hacia el entero más próximo.


[Link](82) // → 82
[Link](2.02) // → 2
[Link](4.001) // → 4
[Link](-4.001) // → -5

[Link]()

[Link](x, y) retorna el valor de x a la potencia y.

[Link](8, 3) // → 512

[Link]()

Retorna la raíz cuadrada de un número.

[Link](64) // → 8

[Link]()

Retorna un número aleatorio, mayor o igual a 0 y menor a 1.

[Link]() // → 0.784405114211054
[Link]() // → 0.81548726640262
[Link]() // → 0.81548726640262
[Link]() // → 0.07392369524727838

Si quisiéramos retornar un número entero dentro de un rango, debemos crear una función
como la siguiente, empleando [Link]():
function enteroAlAzar (min, max) {
return [Link]([Link]() * (max - min) + min);
}

// devuelve un entero mayor o igual a `0` y menor a `10`.


enteroAlAzar(0, 10); // → 9
enteroAlAzar(0, 10); // → 0
enteroAlAzar(0, 10); // → 7
enteroAlAzar(0, 10); // → 5
STRINGS
Los strings son valores de texto. Los caracteres del un string estan indexados, es decir, a
cada uno le corresponde una posición numérica dentro de la cadena de texto, comenzando
por el 0.

Tomemos como ejemplo el siguiente string:

"El gato gris"

La representación de los caracteres indexados se vería entonces así:

0 1 2 3 4 5 6 7 8 9 10 11

E l g a t o g r i s

Por lo tanto, igual que en un array, podemos acceder a un caracter específico de un string
utilizando la siguiente sintaxis:

var texto = "El gato gris";

texto[0]; // → "E"
texto[2]; // → " "
texto[11]; // → "s"

Sin embargo, como ya hemos mencionado, los valores primitivos no son mutables. De
manera que, a diferencia de los array, los caracteres de un string no se pueden modificar.

var texto = "El gato gris";

texto[3] = "p";
texto[4] = "e";
texto[5] = "r";
texto[6] = "r";
texto[7] = "o";

texto; // → "El gato gris";


String()
La función global String() nos permite crear valores de tipo string a partir de cualquier
valor.

String(3.14) // → "3.14"
String(true) // → "true"
String(false) // → "false"
String(function () {}) // → function () {}
String(undefined) // → "undefined"
String(null) // → "null"
String([1, 2, 3]) // → "1,2,3"
String({ a: 1, b: 2 }) // → "[object Object]"
String(NaN) // → "NaN"
String(Symbol()) // → "Symbol()"
String(2 * 3) // → "6"
String(true ? 0 : 1) // → "0"

Para conocer en mayor profundidad las posibilidades que nos da String puedes visitar
este link.

Propiedades y Métodos de String


Podemos conocer todos los métodos de String disponibles explorando el prototipo del
objeto global String en la consola de Google Chrome, utilizando la siguiente expresión:

[Link]

Esto nos va a devolver una lista de métodos similar a la siguiente:


[Link]

length

Mediante la propiedad length podemos conocer la longitud de un string.

var texto = "Aprendiendo JavaScript!";

[Link]; // → 23

indexOf()

El método indexOf() recibe como argumento un string, y devuelve un número que equivale
a la posición en la cual coincide por primera vez el argumento con el string inicial. Si no hay
coincidencias, devuelve -1.

var texto = "El gato en el tejado";

[Link]("en"); // → 8
[Link]("gato"); // → 3
[Link](" "); // → 2
[Link]("perro"); // → -1

replace()

El método replace() reemplaza un fragmento de un string por otro, y retorna un nuevo


string con el resultado.
[Link](valorBuscado, nuevoValor);

Si pasamos como valor buscado un string, replace reemplaza solo la primer coincidencia
en el string inicial.

var a = "dos mas dos son cuatro";


var b = [Link]("dos", "cinco");

a; // → "dos mas dos son cuatro"


b; // → "cinco mas dos son cuatro"

En cambio, si utilizamos expresiones regulares, podemos buscar y reemplazar todas las


repeticiones del valor buscado.

var a = "dos mas dos son seis";


var b = [Link](/dos/g, "tres");

a; // → "dos mas dos son seis"


b; // → "tres mas tres son seis"

Las expresiones regulares son unos patrones utilizados para encontrar combinaciones de
caracteres dentro de un string.

Para utilizarlas con el método replace y reemplazar todas las ocurrencias de un valor en
una cadena de texto, podemos utilizar el siguiente patrón como primer argumento:

/valor buscado/g

Nota como el valor buscado no está rodeado de comillas sino de barras /. La g al final
corresponde a global, y es la que indica que se debe buscar todas las ocurrencias del valor
dentro de una determinada cadena de texto.

concat()

El método concat() une (concatena) uno o más strings, y devuelve un string nuevo.
var nombre = "Lionel";
var nombreCompleto = [Link](" Andrés", " Messi");

nombreCompleto; // → "Lionel Andrés Messi"

Este resultado también puede conseguirse utilizando el operador +.

var nombres = "Lionel";


var nombreCompleto = nombre + " Andrés" + " Messi";

nombreCompleto; // → "Lionel Andrés Messi"

O bien con sintaxis de ES2015, utilizando plantillas de string:

var nombres = "Lionel";


var nombreCompleto = `${nombres} Andrés Messi`;

nombreCompleto; // → "Lionel Andrés Messi"

trim()

El método trim() elimina cualquier espacio vacío antes y después del string, y devuelve un
nuevo string con el resultado.

var conEspacios = " Sigue el camino amarillo ";


var sinEspacios = [Link]();

sinEspacios; // → "Sigue el camino amarillo"

split()

El método split() divide el string en un conjunto de strings y los devuelve en forma de


array. Recibe como argumento un string sobre el cual hacer la división.
var dias = "Lunes - Martes - Miercoles";
var listaDeDias = [Link](" - ");

listaDeDias;
// → ["Lunes", "Martes", "Miercoles"]

toUpperCase() y toLowerCase()

Los métodos toUpperCase() y toLowerCase() transforman la cadena de texto en


mayúsculas y minúsculas, respectivamente, y devuelven un nuevo string con el texto
resultante.

var texto = "El David de Miguel Ángel";


var mayusculas = [Link]();
var minusculas = [Link]();

texto; // → "El David de Miguel Ángel"


mayusculas; // → "EL DAVID DE MIGUEL ÁNGEL"
minusculas; // → "el david de miguel ángel"

Para una lista completa de métodos de String visita este link


OBJETOS
Los objetos en JavaScript son muy similares a los objetos en la vida real. Vamos a tomar
como ejemplo un objeto cotidiano: un automóvil.

Un automóvil tiene ciertas características:

Marca
Modelo
Color
Velocidad máxima
Capacidad de pasajeros
etc

Algunas de estas características podemos modificarlas a voluntad. Por ejemplo, podríamos


pintarlo para cambiar su color. Otras no son modificables, como la marca o el modelo.

Un automóvil tiene también la capacidad de realizar ciertas acciones, como darle arranque,
encender las luces, acelerar, frenar, subir o bajar los cambios, etc.

Los objetos de JavaScript funcionan de forma similar. Poseen características a las cuales
llamamos propiedades, algunas de las cuales podemos modificar, mientras que otras son de
solo lectura. Y también puede realizar acciones, mediante funciones, que al pertenecer a
objetos reciben el nombre de métodos.

JavaScript nos provee una serie de objetos globales que nos permiten realizar diferentes
funciones. Y además nos da la posibilidad de crear nuestros propios objetos.

Literales de Objeto
Un literal de objeto consiste en una serie de propiedades y valores, separados por comas, y
encerrados entre llaves.

Veamos por ejemplo como se vería un automóvil en forma de objeto de JavaScript:

var automovil = {
marca: "Ford",
precio: null,
caracteristicas: {
abs: true,
"velocidad máxima": 289.6,
}
};
Como vemos, nuestro objeto consiste en una serie de propiedades que pueden ser valores de
cualquier tipo, en este caso strings, null, números, booleanos e incluso otro objeto.

Para acceder a las diferentes propiedades de los objetos, lo hacemos con la siguiente
sintaxis:

[Link]; // → "Ford"
[Link]; // → null
[Link]; // → true

// o bien

automovil["marca"]; // → "Ford"
automovil["precio"]; // → null
automovil["caracteristicas"]["abs"]; // → true

Ambas sintaxis en este ejemplo se pueden usar indistintamente. Sin embargo, cuando el
nombre de una propiedad posee caracteres especiales o espacios (como en nuestro ejemplo
la propiedad "velocidad máxima"), debe ser declarada entre comillas, y solo se puede
acceder utilizando la sintaxis con corchetes.

[Link]["velocidad máxima"]; // → 289.6

Una vez creado un objeto, podemos adjuntarle nuevas propiedades más tarde.

[Link] = "Mustang";
[Link] = "Negro";

// o bien

automovil["modelo"] = "Mustang";
automovil["caracteristicas"]["color"] = "Negro";

Nuestros objetos también pueden contener métodos.


[Link] = function () {
// implementación del método
}

[Link] = function () {
// implementación del método
}

Luego para invocar los métodos del objeto utilizamos la siguiente sintaxis:

[Link]();
[Link]();

Veamos una versión alternativa de nuestro objeto automóvil, esta vez con propiedades y
métodos implementados, que luego explicaremos bloque por bloque.
var automovil = {
estado: {
encendido: false,
luces: false,
velocidadActual: 0,
velocidadMaxima: 200
},

encender: function () {
[Link] = true;
[Link] = true;
return [Link];
},
apagar: function () {
[Link] = false;
[Link] = false;
return [Link];
},
acelerar: function () {
if ([Link] &&
[Link] <=
[Link]) {
[Link]++;
}
return [Link];
},
frenar: function () {
if ([Link] &&
[Link] > 0) {
[Link]--;
}
return [Link];
}
}

Nuestro automóvil ahora no solo tiene propiedades sino también métodos capaces de
realizar “acciones”.

Primero le asignamos a la propiedad estado un objeto que a su vez tiene otras propiedades
(que representan el estado del vehículo). Inmediatamente después, creamos 4 métodos que
se encargan de modificar el estado del propio objeto automóvil.

La palabra clave this, cuando se encuentra dentro de un método, hace referencia al objeto
que llama a dicho método. En este caso, como veremos, es el propio objeto automovil.
El método encender() modifica el estado de [Link] y
[Link], y devuelve el objeto estado.

[Link]();

// → {
// → encendido: true,
// → luces: true,
// → velocidadActual: 0,
// → velocidadMaxima: 200
// → }

El método apagar() hace justamente lo contrario.

[Link]();

// → {
// → encendido: false,
// → luces: false,
// → velocidadActual: 0,
// → velocidadMaxima: 200
// → }

Ahora si. ¿Qué es lo mejor que podemos hacer con un automóvil nuevo? ¡Vamos a darle una
vuelta!

[Link]();
[Link](); // → 1
[Link](); // → 2
[Link](); // → 3
[Link](); // → 4

Basándote en lo que ya vimos, ¿puedes inferir qué hace el método acelerar()? Tómate un
momento para analizarlo.

¿Y qué tal frenar()?


[Link](); // → 3
[Link](); // → 2
[Link](); // → 1
[Link](); // → 0

[Link]();

// → {
// → encendido: false,
// → luces: false,
// → velocidadActual: 0,
// → velocidadMaxima: 200
// → }

Objetos anidados
Siguiendo con los automóviles, tomemos como ejemplo los siguientes objetos:

var automovil1 = {
marca: "Audi",
caracteristicas: {
color: "Rojo"
}
}

var automovil2 = {
marca: "BMW",
caracteristicas: [Link]
}

Más tarde en nuestro código hacemos la siguiente modificación:

[Link] = "Gris";

¿Qué color crees que tendrá ahora automovil1?

El siguiente gráfico nos muestra la relación entre ambos objetos.


Al asignar a la propiedad caracteristicas del objeto automovil2 el valor
[Link], estamos haciendo referencia al objeto literal { color:
"Rojo" } creado durante la declaración de automovil1.

Por lo cual, al modificar [Link], estamos modificando el


objeto { color: "Rojo" }, cuyo impacto se vera en ambos automovil1 y automovil2:

[Link] = "Gris";

[Link]; // → "Gris"
[Link]; // → "Gris"

A pesar de tener objetos en apariencia anidados ([Link] anidado


en automovil1), en realidad cada objeto es una entidad independiente. Por lo tanto
debemos ser muy cuidados a la hora de modificar los objetos, asegurándonos de que esto no
genere resultados inesperados en otras partes de nuestro código.

En los casos en que lo deseado sea crear un nuevo objeto “clonado” a partir de otro, podemos
hacerlo utilizando el método [Link](), descrito en la sección siguiente. Por
ejemplo:
var automovil2 = {
marca: "BMW",
caracteristicas: [Link](
{},
[Link]
)
}

[Link]; // → { color: "Gris" }


[Link] = "Negro";
[Link]; // → { color: "Negro" }

[Link]; // → { color: "Gris" }

Métodos de Objeto

Para una lista completa de métodos de objeto visita este link.

[Link]()

El método [Link]() copia las propiedades de uno o más objetos a un objeto


destino, y devuelve el objeto destino modificado (mutado).

[Link](destino, ...objetos)

Por ejemplo:

var objeto = { a: 1, b: 2 };

[Link](objeto, { c: 2 });

objeto; // → { a: 1, b: 2, c: 3 }

Podemos utilizarlo también para crear nuevos objetos, sin mutar el objeto inicial,
simplemente asignándole como primer argumento un literal de objeto vacío:
var objetoInicial = { a: 1, b: 2 };

var nuevoObjeto = [Link]({}, objetoInicial, { c: 2


});

objetoInicial; // → { a: 1, b: 2 }
nuevoObjeto; // → { a: 1, b: 2, c: 3 }

[Link]()

El método [Link]() devuelve un array con los nombres de las propiedades de un


objeto.

var objeto = { a: 1, b: 2, c: 1 };

[Link](objeto); // → ["a", "b", "c"]

[Link]()

El método [Link]() devuelve un array con los valores de un objeto.

var objeto = { a: 1, b: 2, c: 1 };

[Link](objeto); // → [1, 2, 3]

Objetos Globales o Nativos


Además de crear nuestros propios objetos, en JavaScript contamos con una serie de objetos
globales, muchos de los cuales ya vimos. Por ejemplo aquellos que nos sirven para crear y
manipular valores primitivos y objetos:
String
Number
Boolean
Array
Object
Function

Recuerda que estos se pueden utilizar también como funciones para crear nuevos datos:

String("JavaScript")
Number(2020)
Boolean(true)
Array([])
Object({})
Function('return')

Además, el lenguaje nos provee otros objetos con diferentes funcionalidades. Estos son solo
algunos de ellos:

Date
Math
Error
RegExp
Map
Set
JSON
Promise

Para una referencia completa de los objetos globales puedes consultar este link.

¿Todo en JavaScript son Objetos?


Existe un dicho que dice que “en JavaScript todo son objetos”. Esta y otras afirmaciones
erróneas son comunes entre quienes no han dedicado el suficiente tiempo a comprender las
características y mecanismos básicos del lenguaje.

Como ya vimos, en JavaScript no solo hay objetos, sino también valores primitivos. Sin
embargo, al observar la sintaxis de ciertas expresiones de JavaScript, el ojo inexperto podría
cometer el error de caer en esa generalización.
Veamos un ejemplo:

(23).toFixed(2); // "23.00"

[Link](); // "true"

"Hola mundo".split('').reverse().join('');
// "odnum aloH"

—Pero Ariel… ¿¡qué clase de brujería es esa!?

Sobre algunos valores primitivos es posible llamar métodos. Pero lo que sucede en estos
casos no es ningún tipo de magia ni mecanismo misterioso.

Al invocar un método sobre un literal de primitivo como 23, true u "Hola mundo",
JavaScript comprende nuestra intención y convierte este valor en un objeto, de forma
implícita, y luego lleva a cabo nuestra instrucción.

Lo que sucede aquí no es otra cosa que el mecanismo de coerción actuando de forma
implícita, una vez más acudiendo en nuestra ayuda. Esta forma específica de coerción recibe
el nombre de boxing.
ARRAYS
Un array es una colección de elementos. Estos elementos pueden ser combinaciones de
cualquier tipo: primitivos u objetos.

A diferencia de otros objetos, los elementos de un array se encuentran indexados, es decir,


organizados por un índice numérico, y ordenados en base a ese índice.

Un array puede también tener posiciones vacías, o incluso estar completamente vacío.

Para crear un literal de array, simplemente envolvemos una serie de elementos entre
corchetes, y los separamos con comas.

["Juan", "María", "José"]

También podemos crear un array utilizando la función global Array().

Array("Juan", "María", "José")

// o bien

Array(["Juan", "María", "José"])

Podemos acceder a los elementos de un array así como insertar elementos nuevos utilizando
la siguiente sintaxis:

var miArray = ["PI"];


miArray[1] = 3.14;
miArray[2] = null;

miArray; // → ["PI", 3.14, null]


miArray[0]); // → "PI"
[Link]; // → 3

Uso Práctico de Arrays


El array es la estructura de datos en que guardamos elementos en serie.

Supongamos que desde JavaScript hacemos una solicitud asíncrona a un servidor, para que
nos devuelva una lista de productos que se encuentran en un carrito de compras. Esa lista,
sea cual fuere el formato en el que la recibimos del servidor (JSON, XML, etc), es muy
probable que al recibirla debamos transformarla en un array, para luego poder procesarlo, e
iterar sobre sus elementos para mostrarlos en pantalla.

A continuación te presento algunos de los principales métodos de array, que nos van a ser
muy útiles en situaciones como esta.

Métodos de Array
Podemos conocer todos los métodos de Array disponibles explorando el prototipo de la
función global Array en la consola de Google Chrome mediante la siguiente expresión:

[Link]

Lo que nos dará como resultado una lista similar a la siguiente:

[Link]

A continuación vamos a explorar algunos de los métodos más utilizados para la


manipulación de arrays.

Para una lista completa de métodos de array visita este link.

push()

El método push() inserta uno o más elementos al final de un array, y devuelve un número
con su nueva longitud length.

Cada valor que reciba el método como argumento es insertado al final del array. Como
resultado, el array original es modificado.
var animales = ["perro", "gato"];

[Link]("caballo"); // → 3
[Link]("vaca", "conejo"); // → 5

animales;
// → ["perro", "gato", "caballo", "vaca", "conejo"]

concat()

El método concat() concatena dos o más arrays, y devuelve como resultado un array
nuevo, sin modificar el array inicial.

Recibe como argumento cero o más arrays a concatenar con el array inicial. Si no se le pasa
argumentos, devuelve un nuevo array igual al anterior.

var array1 = [1, 2, 3];


var array2 = [4, 5, 6];
var array3 = [7, 8, 9];
var array4 = [Link](array2, array3);

array4; // → [1, 2, 3, 4, 5, 6, 7, 8, 9]

map()

El método map() recibe como argumento una función, comúnmente conocida como
callback, y retorna un nuevo array con el resultado de aplicar esa función a cada uno de sus
elementos.

La función aplicada a map() acepta tres argumentos. El primero de ellos es obligatorio, y es


el valor siendo procesado. Opcionalmente, también acepta:

El índice de posición en el array del valor siendo procesado;


El array sobre el que se llamó el método;

[Link](function callback (valor, indice, array) {


// retornar alguna modificación del valor
})

Por ejemplo:
var numeros = [2, 4, 6, 8, 0];

var numerosMapeados = [Link](


function callback (numero, indice) {
return indice + ": " + numero;
}
)

numerosMapeados; // → ["0: 2","1: 4","2: 6","3: 8","4: 0"]

La función callback puede recibir cualquier nombre, o ser anónima. En este ejemplo la
llamamos sencillamente callback.

También se puede usar como argumento de map(), al igual que de cualquier otra función,
una referencia a una función declarada por separado, lo cual contribuye a que el código sea
más fácil de leer.

var numeros = [2, 4, 6, 8, 0];

function duplicar (numero) {


return numero * 2;
}

[Link](duplicar); // → [4, 8, 12, 16, 0]

reduce()

El método reduce() recibe como argumento una función reductora, y retorna un único
valor basado en la aplicación esa función a cada uno de sus elementos.

Además, el método acepta un segundo argumento opcional para indicar un valor inicial.
var numeros = [0, 1, 1, 2, 3, 5, 8];

var suma = [Link](


function reductor (acumulador, valor, indice, array) {
acumulador = acumulador + valor;
return acumulador
},
0
);

suma; // → 20

La función reductora, requiere los siguientes argumentos:

Un acumulador del valor devuelto por la función en cada llamado. Si se especificó un


valor inicial, el acumulador lo devuelve en el primer llamado;
El valor del array siendo procesado;

Opcionalmente, acepta dos argumentos más:

El índice de posición en el array del valor siendo procesado;


El array sobre el que se llamó el método;

El mismo código del ejemplo anterior podría también escribirse de la siguiente forma:

function reductor (acumulador, valor, indice, array) {


acumulador = acumulador + valor;
return acumulador
}

var numeros = [0, 1, 1, 2, 3, 5, 8];


var suma = [Link](reductor, 0);

suma; // → 20

filter()

El método filter() recibe como argumento una función filtro, y retorna un nuevo array
con los elementos que cumplan la condición implementada por esa función.

El nombre de este método puede generar confusión, dado que estamos acostumbrados a que
cuando hablamos de un filtro, solemos pensarlo como algo que excluye, es decir, lo que
podríamos llamar un filtro exclusivo.
Sin embargo, la función filtro en JavaScript se encarga de detectar a los valores que serán
incluídos en el resultado, y es por lo tanto un filtro inclusivo.

var numeros = [-10, 100, -25, 340, 0, -2, 45];

// retorna los números mayores a 0


function filtro (numero, indice, array) {
return numero > 0;
}

var numerosPositivos = [Link](filtro);


numerosPositivos; // [100, 340, 45]

La función filtro recibe los mismos argumentos que map():

El valor siendo procesado;


El índice del valor siendo procesado (opcional);
El array sobre el que se llamó el método (opcional);

Si ningún elemento cumple la condición de la función filtro, el método filter() devuelve


un array vacío.
COERCIÓN
La coerción es el mecanismo de ciertos lenguajes de programación, incluído JavaScript, por
el cual un valor es convertido de un tipo a otro.

Es un proceso que suele ser desconocido, o en ocasiones simplemente evitado por algunos
programadores, argumentando que es un comportamiento errático o un defecto de
JavaScript.

Por el contrario, el mecanismo de coerción sigue reglas y algorítmos específicos, detallados


en el estándar ECMAScript. Por lo cual, conocer sus reglas y dominarlo nos permitirá
utilizarlo a nuestro favor para hacer un mejor uso del lenguaje, evitando introducir bugs en
nuestro código.

Cualquier valor, sea primitivo u objeto, es posible de ser coercionado o convertido. La


coerción puede suceder de dos formas: implícita y explícita.

Coerción Implícita
La coerción implícita es la que lleva a cabo JavaScript de forma automática.

En el capítulo sobre booleanos hablamos de valores truthy y falsy. Lo que hace posible que
valores de diferentes tipos sean convertibles a booleano en determinados contextos, no es
otra cosa que un proceso de de coerción implícita. Por ejemplo, dado el siguiente código:

var numero = 1;
var texto = "";

if (numero) {
[Link]("numero es verdadero");
}

texto
? [Link]("texto es verdadero")
: [Link]("texto es falso");
// → "texto es falso"

JavaScript lo interpreta de la siguiente manera:


var numero = 1;
var texto = "";

if (Boolean(numero)) {
[Link]("numero es verdadero");
}

Boolean(texto)
? [Link]("texto es verdadero")
: [Link]("texto es falso");
// → "texto es falso"

Operadores de Igualdad (==)

El operador de igualdad == utiliza el mecanismo de coerción de forma implícita. Este simple


operador de dos caracteres utiliza internamente un algoritmo de 13 pasos para determinar si
dos valores son o no iguales (no es necesario conocerlas, pero si comprender que no hay
nada de azaroso ni errático en la forma en que este operador funciona).

Dada la complejidad de este operador, vamos a centrarnos únicamente en algunas de sus


reglas principales.

1. Si ambos valores son del mismo tipo, el operador == utiliza el mismo mecanismo que
===.

2. si uno de los operandos es null y el otro undefined, la comparación devuelve true.

null == undefined // true


undefined == null // true

3. Los operandos de tipo string y boolean son convertidos a number:

3 == "3" // true

// dado que...
Number("3") // → 3
3 == Number("3") // → true
1 == true // → true

// dado que...
Number(true) // → 1
1 == Number(true) // → true

0 == false // → true

// dado que...
Number(false) // → 0
0 == Number(false) // → true

Por último, los objetos son convertidos a valores primitivos. Ahora bien, esta conversión a
primitivo también sucede según una serie de reglas sobre las cuales no vamos a profundizar
aquí. Lo recomendable es ser consciente en todo momento de los tipos de datos que estamos
comparando, para evitar obtener resultados inesperados.

Boxing

Un tipo particular de coerción implícita es el llamado boxing, que sucede cuando invocamos
una propiedad o método sobre un valor primitivo. En estos casos, JavaScript promueve el
valor al tipo object, para asi poder llevar a cabo nuestro requerimiento.

Por ejemplo:

Cuando hacemos… JavaScript interpreta…

"Ariel Fuggini".split(" String("Ariel Fuggini").split("


") ")

"JavaScript".length String("JavaScript").length

(23.5).toFixed(3) Number(23.5).toFixed(3)

[Link](3) Number(23.5).toFixed(3)

[Link]() Boolean(true).toString()
Coerción Explícita
La coerción explícita es aquella que logramos intencionalmente mediante el uso de
funciones u operadores. Por ejemplo:

// coerción a boolean
var numero = 42;
Boolean(numero); // → true
!numero; // → false
!!numero; // → true

// coerción a string
String(numero); // → "42"
numero + ""; // → "42"
`${numero}`; // → "42"
[Link](); // → "42"

// coerción a number
var texto = "42";
Number(texto); // → 42
+texto; // → 42
++texto; // → 43
texto++; // → 43
TEMPORIZADORES
En JavaScript contamos con dos métodos globales que nos permiten llamar a una función
luego de un tiempo determinado.

setTimeout()

setTimeout(funcion, delay, ...argumentos)

El método global setTimeout() recibe como primer argumento la función a llamar o una
referencia a ella.

El segundo argumento representa el delay o tiempo de espera hasta llamar a la función,


expresado en milisegundos.

Y, opcionalmente, podemos pasarle tantos argumentos como querramos que reciba a la


función.

function suma (a, b) {


[Link](a + b);
}

var temporizador = setTimeout(suma, 2000, "Java",


"Script");

// 2 segundos (2000 ms) después...


// -> "JavaScript"

Si deseamos cancelar la llamada a la función antes de los 2000 ms, podemos hacerlo
utilizando el método global clearTimeout() pasándole como argumento la referencia al
temporizador.

clearTimeout(temporizador);

setInterval()
El método global setInterval() funciona de la misma forma que setInterval(), con la
única diferencia que la función se sigue llamando indefinidamente en los intervalos
indicados, hasta que la detengamos o cerremos la ventana del navegador.
setInterval(funcion, delay, ...argumentos)

Por ejemplo:

function suma (a, b) {


[Link](a + b);
}

var intervalo = setInterval(suma, 2000, "Java", "Script");

// 2 segundos (2000ms) después...


// -> "JavaScript"

// 2 segundos (2000ms) después...


// -> "JavaScript"

// 2 segundos (2000ms) después...


// -> "JavaScript"

// ...

Para interrumpir el intervalo, utilizamos el método global clearInterval().

clearInterval(intervalo);
MANIPULANDO EL DOM
El DOM o Document Object Model, lo que podríamos traducir como Modelo de Objetos del
Documento, es una representación, estructurada y orientada a objetos, de un documento
web.

A través de JavaScript podemos interactuar con esta estructura y modificarla, y así alterar la
representación en el navegador de nuestros documentos web, su estilo, su estructura, y su
contenido.

La estructura del DOM tiene una jerarquía de árbol. Por eso es normal referirse a él como
Árbol del DOM (DOM Tree).

En las ramas de ese árbol se encuentran nodos, cada uno de los cuales representa un
elemento del documento.

Por ejemplo, dado el siguiente código HTML:

<html>
<head>
<title>Ejemplo</title>
</head>
<body class="home">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</body>
</html>

Una vez parseado este código por el navegador, el HTML pasa a convertirse en un árbol de
nodos que podría representarse gráficamente este de la siguiente forma:
Árbol del DOM

JavaScript nos permite interactuar con este árbol de nodos de la misma forma que
interactuamos con otros objetos. Podemos leerlos, modificarlos, eliminarlos y agregar
nuevos.

El DOM no es un lenguaje de programación en sí, sino que es una Interfaz de Programación de


Aplicaciones, o API, que forma parte del grupo de las llamadas APIs Web. Estas APIs
permiten realizar diferentes tareas dentro de un contexto web utilizando JavaScript.

El DOM, entonces, es la API que le permite a JavaScript realizar una de sus tareas más
importantes en el contexto de un documento web, como es la de controlar y manipular sus
elementos.

Si bien originalmente JavaScript y el DOM fueron desarrollados en paralelo, con el tiempo


continuaron su evolución de forma independiente. Hoy en día, el DOM tiene su propia
especificación, y es posible interactuar con su API utilizando diferentes lenguajes de
programación, como Java o PHP.

En esta sección vamos a explorar las formas de interactuar con el DOM utilizando JavaScript,
los objetos que tenemos disponibles para hacerlo, y sus principales métodos.

Selectores
En JavaScript contamos con una serie de métodos denominados selectores que nos permiten
seleccionar elementos de nuestro documento, y luego tratarlos como objetos: consultar y
modificar sus propiedades, e invocar sus métodos.

Veamos cómo funcionan estos métodos. Para eso nos basaremos en el siguiente fragmento
de HTML:

<ul>
<li id="primero" class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>

getElementById()

Recibe como argumento un string, y retorna un único nodo cuyo atributo id se corresponda
con eél. Cabe recordar que en HTML, un valor de atributo id debe ser utilizado solo una vez
en cada documento.

var primerItem = [Link]("primero");

primerItem;
// → <li id="primero" class="item">Item 1</li>

getElementsByClassName()

Recibe como argumento un string, y retorna una colección de nodos cuyo atributo class se
corresponda con él.

var items = [Link]("item");

[Link]; // → 3

Cuando un selector, cualquiera sea, devuelve una colección de nodos, podemos contar la
cantidad de items que contiene mediante la propiedad length, así como acceder a los
diferentes elementos de esta colección, de la misma forma que lo hacemos en un array.

items[1];
// → <li class="item">Item 2</li>
getElementsByTagName()

Recibe como argumento un string que corresponde al nombre de una etiqueta HTML, y
retorna una colección de nodos que coinciden con esa etiqueta.

var items = [Link]("li");

[Link]; // → 3

querySelector()

Recibe como argumento un string que corresponde con uno o más selectores CSS separados
por comas, y retorna el primer nodo que coincida con el selector.

var primerItem = [Link]("ul [Link]");

primerItem;
// → <li id="primero" class="item">Item 1</li>

querySelectorAll()

Recibe como argumento un string que corresponde con uno o más selectores CSS separados
por comas, y retorna una lista de nodos que coincidan con el selector.

var items = [Link]("ul [Link]");

[Link]; // → 3

Insertando Contenido
Mediante las propiedades innerText e innerHTML podemos manipular el contenido de
texto y el HTML dentro de un elemento del DOM.
var items = [Link]("ul [Link]");

items[1]; // → <li class="item">Item 2</li>


items[1].innerText; // → "Item 2"

items[1].innerText = "Segundo item";


items[1]; // → <li class="item">Segundo item</li>

items[2]; // → <li class="item">Item 3</li>


items[2].innerHTML; // → "Item 3"
items[2].innerHTML = "<strong>Tercero</strong>";
items[2].innerHTML; // → <strong>Tercero</strong>
items[2];
// → <li class="item"><strong>Tercero</strong></li>

Crear Nuevos Elementos

createElement()

El método createElement() nos permite crear un nuevo elemento nodo. Recibe como
argumento obligatorio el nombre del elemento a crear.

[Link](nombreDelElemento)

Supongamos que queremos insertar un nuevo <div> en nuestro documento:

var div = [Link]("div");

div; // → <div></div>

Como vemos, createElement() nos retorna un nuevo elemento <div>, que almacenamos
en la variable div.

—Pero… ¿Y dónde se muestra mi <div>?

¡Tranquilo! El <div> aun no se muestra en pantalla, solo esta guardado en memoria. Mas
adelante lo insertaremos en el DOM. Pero primero, vamos a hacerle algunas modificaciones.

Si ya haz creado documentos HTML en el pasado, sabes que un <div> vacío no nos mostrará
nada en patalla. Así que vamos a darle algo de contenido.
[Link] = "Aprendiendo JavaScript";

div;
// → <div>Aprendiendo JavaScript</div>

¡Ahora nuestro <div> tiene contenido!

Aunque a decir verdad, un <div> no tiene ningún formato. Entonces, hagamos que su
contenido sea mejor un encabezado. Para eso utilizaremos la etiqueta <h1>.

Para eso creamos un nuevo elemento <h1>:

var encabezado = [Link]("h1");


[Link] = "Manipulando el DOM";

encabezado;
// → <h1>Manipulando el DOM</h1>

Ya tenemos nuestros <div> y <h1> listos. ¿Cómo reemplazamos el viejo texto por nuestro
nuevo encabezado?

replaceChild()

El método replaceChild() nos posibilita reemplazar un nodo por otro. Recibe dos
argumentos, el nuevo nodo y el nodo a reemplazar.

[Link](nuevoNodo, viejoNodo)

Volviendo a nuestro <div>, vamos a cambiar su viejo texto plano por nuestro nuevo <h1>.

Para comenzar debemos saber que un texto es también en sí un nodo del DOM, en este caso
de tipo Text, mientras que nuestros <div> y <h1> son nodos de tipo Element.

Entonces, sabiendo esto, lo que queremos hacer ahora es reemplazar nuestro anterior nodo
de texto, por el nuevo nodo elemento.

Para ello nos serviremos con la propiedad childNodes que poseen los nodos del DOM, y
que nos retorna un objeto NodeList con los nodos hijo del nodo en cuestión.
var viejoNodoDeTexto = [Link][0];

viejoNodoDeTexto; // → "Aprendiendo JavaScript"

[Link](encabezado, viejoNodoDeTexto);

div;
// → <div>
// → <h1>Manipulando el DOM</h1>
// → </div>

¿Genial, no? Vamos por más.

Ahora vamos a agregar un párrado a nuestro <div>. Para ello creamos un nuevo elemento
<p>.

var parrafo = [Link]("p");


[Link] = "Adjuntando nodos.";

parrafo; // → <p>Adjuntando nodos.</p>

Tenemos ahora un nuevo desafío. ¿Cómo insertamos el nuevo párrafo dentro de nuestro
<div> e inmediatamente después del <h1>?

appendChild()

Utilizando el método appendChild() podemos adjuntar un nuevo elemento nodo dentro


de un elemento padre. Simplemente invocamos el método sobre div pasándole como
argumento el nuevo nodo.

[Link](parrafo);

div;
// → <div>
// → <h1>Manipulando el DOM</h1>
// → <p>Adjuntando nodos.</p>
// → </div>

¡Voilà! Nuestro div sigue creciendo, igual que nuestra habilidad para manipular el DOM.
¿Qué sucede si de repente recordamos (porque nos distrajimos entre tantos métodos) que
queríamos otro párrafo antes del actual?

Nuestra primer reacción podría ser: —¡Al diablo! [Link] y listo.

Por suerte, una fracción de segundo después recordamos que queremos ser programadores
metódicos y responsables, y decidimos seguir explorando las posibilidades que nos da
JavaScript.

cloneNode()

Mediante cloneNode() podemos literalmente clonar un nodo del DOM.

Veamos cómo funciona clonando nuestro párrafo:

var parrafo2 = [Link](true);

parrafo2; // → <p>Adjuntando nodos.</p>

Con el argumento true lo que hacemos es decirle a cloneNode() que queremos clonar el
nodo y todos sus nodos hijo, incluyendo los de texto.

Sin embargo, en nuestro ejemplo queremos un texto diferente, asi que clonaremos
únicamente el nodo, sin hijos, y luego le adjuntaremos nuestro texto deseado. Esta vez,
usaremos un nuevo método, createTextNode(), que funciona igual que
createElement() pero para nodos de texto.

parrafo2 = [Link]();

parrafo2; // → <p></p>

var texto = [Link]("JavaScript es


genial!");
[Link](texto);

parrafo2; // → <p>JavaScript es genial!</p>

¡Ahora sí! Estamos un paso más cerca de nuestro objetivo de mostrar el contenido en
pantalla.

insertBefore()
El método insertBefore() acepta dos argumentos, un nuevo nodo a insertar y uno
existente de referencia, y como resultado, insertará el primero justo antes del segundo.

[Link](nuevoNodo, nodoExistente)

Usemos entonces este método para insertar nuestro nuevo <p> clonado antes de nuestro
anterior <p>.

[Link](parrafo2, parrafo);

div;
// → <div>
// → <h1>Manipulando el DOM</h1>
// → <p>JavaScript es genial!</p>
// → <p>Adjuntando nodos.</p>
// → </div>

Nuestro <div> ya está lo suficientemente maduro para mostrarlo en el navegador.

Para lograrlo, debemos ahora adjuntarlo a cualquier elemento existente y visible. En este
caso, lo adjuntaremos directamente en el <body> de nuestro documento.

Para ello, podemos utilizar appendChild() de la forma que vimos anteriormente.

[Link](div);

[Link]; // → para ver el resultado

Si el body de nuestro documento web estaba vacío, debería ahora verse de la siguiente forma:

<body>
<div>
<h1>Manipulando el DOM</h1>
<p>JavaScript es genial!</p>
<p>Adjuntando nodos.</p>
</div>
</body>

¡Felicitaciones! Hemos creado y manipulado elementos del DOM, y sin necesidad de ninguna
librería o framework.
En ocasiones tendremos la necesidad también de manipular elementos ya visibles del
documento. Para ello nos serviremos de los mismos métodos, en combinación con los
selectores.

Por ejemplo, ¿qué haríamos si quisiéramos remover uno de los párrafos del nuevo <div>?

remove() y removeChild()

remove() y removeChild() nos permiten eliminar elementos del DOM. remove() es un


poco mas sencillo para usar, aunque no es compatible con Internet Explorer 11 y versiones
anteriores (en los cada vez menos frecuentes casos en que debamos dar soporte a este
navegador).

[Link]();
[Link](nodoHijo);

Para remover uno de los párrafos dentro de nuestro <div> podemos hacerlo de dos formas:
si aun tenemos acceso a las variables que creamos anteriormente, podemos reutilizarlas para
referirnos a los mismos elementos del DOM que ahora son visibles. Si no, podemos volver a
crear referencias a esos elementos utilizando selectores.

// creamos nuevas referencias si hace falta


var div = [Link]("div");
var parrafo = [Link][2];

// y luego modificamos
[Link]();

// o bien
[Link](parrafo);

Manipulando Atributos
Cuando necesitemos agregar, modificar y/o remover atributos de los diferentes nodos del
DOM, contamos con métodos para este fin.

En los siguientes ejemplos continuamos utilizando los elementos que creamos


anteriormente.

setAttribute()
El método setAttribute() modifica un atributo del nodo, y si el atributo no existe, lo
crea.

Acepta dos argumentos, el nombre y el valor del atributo respectivamente.

[Link]("id", "contenedor");
[Link]("style", "color: blue;");

div;
// → <div id="contenedor">
// → <h1 style="color: blue;">Manipulado el DOM</h1>
// → ...
// → </div>

getAttribute()

El método getAttribute() devuelve el valor de un atributo.

[Link]("id"); // → "contenedor"
[Link]("style"); // → "color: blue;"

removeAttribute()

El método removeAttribute() borra un atributo del elemento.

[Link]("id");
[Link]("style");

div;
// → <div>
// → <h1>Manipulado el DOM</h1>
// → ...
// → </div>

Manipulando Clases
El atributo class se utiliza frecuentemente para asociar estilos CSS a los elementos de
nuestro HTML. Poder modificar este atributo de forma dinámica con JavaScript nos resultará
de utilidad.

className

La propiedad className nos da acceso a la clase o clases de un elemento nodo, en forma de


string y separadas por espacios.

[Link] = "seccion";
[Link]; // → "seccion"

[Link] += " contenido";


[Link]; // → "seccion contenido"

div;
// → <div class="seccion contenido">...</div>

classList

La propiedad classList nos devuelve un objeto que contiene las diferentes clases del
elemento, accesibles mediante su índice.

[Link];
// → ["seccion", "contenido", ...]

[Link][0]; // → "seccion"
[Link][1]; // → "contenido"

[Link]; // → "seccion contenido"

Para remover una clase podemos utilizar [Link]():

[Link]("contenido");

[Link]; // → "seccion"

div; // → <div class="seccion">...</div>

Para agregar una clase contamos con el método [Link]():


[Link]("principal");

[Link]; // → "seccion principal"

div;
// → <div class="seccion principal">...</div>

Para alternar la presencia de una clase usamos el método [Link]():

[Link]; // → "seccion principal"

[Link]("seccion");
[Link]; // → "principal"

[Link]("seccion");
[Link]; // → "seccion principal"
EVENTOS DEL DOM
Imaginemos por un momento que queremos saber en JavaScript cada vez que un botón de
nuestra página web es clickeado. ¿Cómo haríamos para resolver esta necesidad con lo que
conocemos hasta ahora?

Quizás nos veríamos tentados a crear una función que determine el estado del botón. Ahora
bien, para enterarnos lo suficientemente rápido si ese botón fue presionado o no,
deberíamos chequear el estado del botón una y otra vez.

Supongamos entonces que usamos la función setInterval(), que nos permita llamar a
esa función cada, digamos, 100 milisegundos. Esta implementación se vería algo así:

setInterval(function observarBoton () {
// determinar el estado del botón
}, 100);

Ahora, imaginemos que tenemos 10 botones en pantalla. Tendríamos entonces 10


temporizadores, generando 10 llamados a la función cada 100 ms, es decir, un total de 100
llamados por cada segundo que el usuario esta corriendo nuestra página web.

A medida que nuestras páginas se volvieran más complejas, comenzarían también a volverse
ineficientes, al sobrecargarlas de llamados constantes a funciones por si acaso algo hubiera
sucedido. Esto causaría que el navegador consuma una cantidad innecesaria de memoria,
podría empezar a bloquearse la interfaz de usuario, etc.

Afortunadamente, existe un mecanismo mucho más eficiente y amigable que el que


acabamos de describir, que es posible gracias a un subconjunto de APIs Web dedicadas al
manejo de Eventos del DOM.

La API de Eventos del DOM nos sirve para volver a nuestro JavaScript reactivo ante
determinados sucesos en nuestra interfaz web.

Algunos de los eventos más comunes que podemos controlar con JavaScript son:

Eventos del mouse: click, doble click, posar el cursor;


Eventos del teclado: presionar y soltar teclas;
Eventos de formularios: enviar, resetear;
Eventos de campos de formulario: cambiar, seleccionar, enfocar, desenfocar;
Eventos de la ventana del navegador: cargar, hacer scroll, cambiar el tamaño;

Existen innumerables usos prácticos para los Eventos del DOM. Algunos de los que vemos
con frecuencia en los sitios con los que interactuamos a diario son:

Al hacer click en un botón, abrir una nueva ventana tipo popup;


Desplegar nuevos campos de un formulario al seleccionar cierta opción de un campo
desplegable;
Al enviar un formulario, validar cada campo, y cancelar el envío si hay errores;

Observando Eventos
Los elementos del DOM cuentan con el método addEventListener(), que nos permite
asociar un evento determinado con una función controlador de evento (event handler en
inglés).

[Link](
evento, // string
controlador, // función
usar_captura // booleano (opcional)
)

Veamos un ejemplo. Dado el siguiente fragmento de HTML:

<button id="boton">Hola</button>

Declaramos un observador de evento:

var boton = [Link]("boton");


[Link]("click", onClick);

function onClick (event) {


[Link] = "red";
}

Observamos el evento click sobre el elemento boton. Cuando se dispara este evento
(cuando el usuario hace click en el botón), se invoca a la función controlador onClick, que
modifica el color de fondo del botón a rojo.

Analicemos ahora uno por uno los parámetros que recibe el método addEventListener().

Controlador de Evento
La función controlador es la que determina la acción a realizar al dispararse el evento.

Recibe como primer argumento un objeto de tipo Event, que contiene propiedades y
métodos relacionados con el evento disparado.
En el ejemplo anterior, el valor recibido por el parámetro event es más específicamente de
tipo MouseEvent, un tipo de evento “hijo” de Event, que recibe información adicional en
relación al mouse, como por ejemplo las coordenadas de la pantalla en las que se hizo click, y
qué botón del mouse se presionó.

Dentro de una función controlador, la palabra clave this hace referencia al elemento del
DOM que disparó el evento, en este caso el botón. En el ejemplo, this nos es equivalente a
utilizar la variable boton, ya que ambas hacen referencia a nuestro elemento <button>.

Evento
El parámetro evento consiste en un string correspondiente al nombre del evento a observar.

Existe una gran cantidad de eventos que podemos controlar en JavaScript. A continuación
nombro un pequeño grupo de los que se utilizan con mayor frecuencia:

Eventos del mouse

click
dblclick
mouseover
mouseout
mousemove

Eventos del teclado

keyup
keydown

Eventos de formularios

change
submit
focus
blur

Eventos de la ventana e interfáz de usuario

load
error
resize
scroll
beforeunload
unload
Para una referencia completa de eventos disponibles y ejemplos de uso, visita este link.

Un ejemplo práctico

El evento click es uno de los que más frecuentemente nos tocará controlar. Se puede
observar en cualquier elemento de un documento HTML, excepto en algunos pocos como
<iframe>, <br> y otros a los que simplemente no es posible hacer click, como <head> o
<title>.

Veamos un ejemplo práctico de manejo de este evento:

<style>.hidden { display: none }</style>

<a href="[Link]" class="link">Mostrar</a>

<div id="contenido" class="hidden">


<h3>Top Secret</h3>
<p>Este contenido esta oculto.</p>
</div>

var link = [Link](".link");


var contenido = [Link]("#contenido");

[Link]("click", mostrarContenido);

function mostrarContenido (event) {


[Link]();
[Link]("hidden");
[Link] = [Link]("hidden")
? "Mostrar"
: "Ocultar";
}

Creamos un elemento HTML <a> que será sobre el cual observamos los clicks, y un <div>
que inicialmente ocultamos con la clase hidden.

Luego con JavaScript observamos los click sobre el <a> con addEventListener(), y
establecemos una función mostrarContenido() como controlador.

Dentro de mostrarContenido() lo que hacemos es, primero, utilizando el método


preventDefault() del objeto event prevenimos cualquier acción por defecto del <a>, en
este caso, para evitar abrir [Link] y permanecer en la página actual.

Luego, con el método [Link]() alternamos la presencia de la clase hidden en


nuestro <div>, lo que a su vez alterna su visibilidad.

Por último, utilizamos [Link] para modificar el texto del <a> según la visibilidad
del contenido. Para saber si el contenido esta visible o no, usamos
[Link]() para detectar la presencia de la clase hidden. Y luego utilizamos
un condicional ternario para decidir entre "Mostrar" y "Ocultar".

En este ejemplo comenzamos a poner en práctica varias de las herramientas adquiridas


hasta ahora. Si el ejemplo te resulta algo complejo, te invito a repasar el código y la
explicación nuevamente las veces que sea necesario, y a ponerlo en práctica en tu
editor de código.

Propagación del Evento


Supongamos que tenemos el siguiente documento HTML:

<html>
<body>
<div id="contenido">
<button id="boton">Clickeame</button>
</div>
</body>
</html>

Entonces queremos observar los clicks tanto en <body> como en <div> y <button>:

var contenido = [Link]("contenido");


var boton = [Link]("boton");

[Link]("click", function (e) {


[Link]("click en body");
});
[Link]("click", function (e) {
[Link]("click en contenido");
});
[Link]("click", function (e) {
[Link]("click en botón");
});
Al hacer click en <button> no solo estamos disparando el evento click en él, sino también
en todos sus ancestros: <div>, <body>, <html>, y además document y window.

Entonces ¿en qué orden se invocarán nuestros controladores de evento?

El concepto de propagación del evento es lo que viene a resolver este dilema.

Los eventos se propagan en dos fases. La primera fase es la de captura (capture). Durante
esta fase el evento se propaga desde el objeto window hacia el nodo que disparó el evento,
llamado objetivo (target). En esta fase, el nodo objetivo es el último en manejar el evento.

La segunda fase es la de burbujeo (bubbling). En esta fase sucede exactamente lo opuesto: el


evento se maneja primero en el nodo objetivo, y luego se propaga por todos sus nodos
ancestro hasta llegar al objeto window.

Fases de propagación del evento

Por lo tanto, el orden en que se manejarán los eventos dependerá lo que le comuniquemos al
respecto a addEventListener() al invocarlo.

Recordemos los parámetros aceptados por el método:

[Link](
evento, // string
controlador, // función
usar_captura // booleano (opcional)
)
El tercer parámetro usar_captura es opcional y es el que vamos a usar para indicarle
nuestra intención de propagación.

Si deseamos manejar el evento en fase de captura, debemos asignarle el valor true. Si por el
contrario, queremos hacerlo en fase de burbujeo, le asignamos false. Este último es el
valor que recibe el parámetro por defecto.

En nuestro código de ejemplo, no le asignamos ningún valor a este parámetro y por lo tanto
se asume false, manejándose los tres en fase de burbujeo, resultando en el siguiente
orden:

1. <button>
2. <div>
3. <body>

Y por lo tanto la salida a consola será:

// -> "click en botón"


// -> "click en contenido"
// -> "click en body"

Otra forma de comprender el orden en que se manejarán los eventos, es pensándolo de la


siguiente forma:

Si todos los nodos de nuestro documento de ejemplo estuvieran observando el evento


click, el orden den que se manejaría el evento en los diferentes nodos sería el siguiente,
independientemente del orden en que los declaremos en el código:
function ctrl (evento) {
// ...
}

// inicio de fase de captura


[Link]("click", ctrl, true);
[Link]("click", ctrl, true);
[Link]("click", ctrl, true);
[Link]("click", ctrl, true);
[Link]("click", ctrl, true);
[Link]("click", ctrl, true);
// fin de fase de captura

// inicio de fase de burbujeo


[Link]("click", ctrl, false);
[Link]("click", ctrl, false);
[Link]("click", ctrl, false);
[Link]("click", ctrl, false);
[Link]("click", ctrl, false);
[Link]("click", ctrl, false);
// fin de fase de burbujeo

Dejar de Observar Eventos


En ocasiones necesitaremos desasociar un controlador de evento de un elemento, por
ejemplo para liberar memoria o prevenir resultados no deseados. En ese caso debemos
utilizar el método removeEventListener(), pasándole los mismos argumentos con los
que se invocó addEventListener().

[Link](evento, controlador,
usar_captura)

Por ejemplo:
var boton = [Link]("boton");
[Link]("click", onClick, true);

function onClick (event) {


[Link] = "red";
}

// mas tarde...

[Link]("click", onClick, true);


ECMASCRIPT 2015
ECMAScript 2015, también conocido como ES2015 o ES6, es posiblemente la versión de este
estándar que introdujo las novedades más significativas al lenguaje.

Existe la idea de que algunas de las nuevas características que introduce cada nueva versión
de ECMAScript llegan para reemplazar características anteriores. Particularmente dos de las
características de ES2015, la función flecha, y las nuevas palabras clave let y const.

Y entonces es fácil caer en la tentación de limitarse exclusivamente a utilizar, por ejemplo, la


sintaxis de función flecha, y olvidarse para siempre de la palabra clave function. O
apresurarse a realizar una búsqueda de la palabra var en nuestro viejo código, y sin más,
reemplazar cada coincidencia por let.

Esto sería sencillamente un grave error. Tanto la función flecha, como let y const, no son
mejores que sus antecesoras, sino diferentes. Como anticipé en la introducción, en
ECMAScript lo nuevo no necesariamente viene a reemplazar a lo viejo.

En lugar de eso, debemos evitar apresurarnos a elegir la novedad sin previo análisis, y
tomarnos el tiempo para conocer con la mayor profundidad posible cada una de las nuevas
características, tomándolas como herramientas adicionales de las que disponemos para
utilizar a conciencia, y en muchas ocasiones, en conjunto con las anteriores.

let y const
Las palabras clave let y const nos sirven para declarar variables variables, similar a var,
pero con algunas diferencias importantes.

La primera diferencia radica en su ámbito de alcance. Mientras que el ámbito de las variables
declaradas con var lo define la función, el ámbito de let y const es a nivel de bloque. Esto
incluye tanto funciones, como cualquier sentencia de las que explicamos en la sección
Control de flujo:

Sentencias bloque
Sentencias condicionales
Sentencias de iteración
Sentencias switch

Veámoslo a través del siguiente ejemplo:


function miFuncion () {
if (true) {
var a = 1;
let b = 2;
const c = 3;
}

a; // → 1
b; // → undefined
c; // → undefined
}

miFuncion();
// → ReferenceError: b is not defined

En este fragmento, a al ser declarada con var queda disponible dentro del ámbito de la
función que la contiene, miFuncion(). Sin embargo, el alcance de b y c, al estar declaradas
con let y const,respectivamente, queda limitado al ámbito del bloque condicional if.

Por lo cual, al invocar a la función miFuncion(), cuando intentamos obtener el valor de b y


c fuera del condicional, lo que recibimos es un error de tipo ReferenceError anunciando
que b no ha sido definida.

La segunda diferencia con var es la capacidad de ser redeclaradas. Mientras que var permite
volver a declarar variables existentes con el mismo nombre, tanto let como const solo
pueden declararse una vez.
var a = false;
let b = 1;
const c = null;

// ...

var a = true;
a; // → true

// todas las siguientes provocan `SyntaxError`


var b = 2;
var c = "";
let a = false;
let b = 2;
let c = {};
const a = [];
const b = 3;
const c = undefined;

La tercer distinción tiene que ver con la posibilidad de reasignar el valor de la variable. Tanto
var como let permiten ser reasignadas a lo largo de nuestro código, es decir, pueden
cambiar su valor. Sin embargo, una variable const debe obligatoriamente recibir un valor al
ser declarada, y no podrá cambiar de valor.

var a = 1;
a = true;
a; // → true

let b = 2;
b = false;
b; // → false

const c = 3;
c = {};
// → TypeError: Assignment to constant variable.

En la siguiente tabla comparativa podemos ver las principales características de las


diferentes palabras claves.
Palabra Clave Ámbito Reasignable Redeclarable

var Función Si Si

let Bloque Si No

const Bloque No No

const no es constante

Es importante tener en cuenta que, si bien el nombre sugiere que const nos permite crear
constantes, es decir, valores inmutables, en realidad esto no es preciso.

Veamos un ejemplo:

// creamos un objeto
const objeto = { a: 1, b: 2 };

// le agregamos una nueva propiedad


objeto.c = 3;

// el objeto fue mutado


objeto; // → { a: 1, b: 2, c: 3 };

Como vemos, aunque usemos const, logramos mutar el objeto agregándole una propiedad
nueva. Con lo cual, considerar const una constante es engañoso. En lugar de eso, debemos
limitarnos a definir las variables const simplemente como variables no reasignables.

Función Flecha
La función flecha consiste en una nueva sintaxis para declarar una función.

Veamos algunos ejemplos. Estas son algunas formas de declarar una función “clásica”:
function saludar (nombre) {
return "Hola " + nombre;
}

// o bien

var saludar = function (nombre) {


return "Hola " + nombre;
}

La misma función con la nueva sintaxis se vería así:

let saludar = (nombre) => {


return "Hola " + nombre;
}

// o bien

let saludar = nombre => "Hola " + nombre;

Como vemos, en los casos en que la función flecha consiste en una sola sentencia, esta puede
ser declarada en una sola línea.

Por otra parte, si la función tiene un solo parámetro, los paréntesis pasan a ser opcionales.

La función flecha se vuelven muy útil para trabajar con funciones de orden superior, es decir
las que toman como parámetro una función, y/o retornan una función como resultado.

La sintaxis de la función flecha se vuelve entonces especialmente sintética en estos casos:


// función clásica
function sumar (a) {
return function (b) {
return function (c) {
return a + b + c;
}
}
}

// función flecha
const sumar = a => b => c => a + b + c;

// ambas se invocan de la misma forma


sumar(2)(3)(6); // → 11

Plantillas de Cadena de Texto


La plantilla de cadena de texto, o bien plantilla de string o literal de plantilla es una nueva
sintaxis para literales de texto. Una de sus principales características es la posibilidad de
incrustar expresiones dentro de ellas.

// ES5
var texto = "El " + animal + " es de color " + color;
var suma = "El resultado es " + (2 + 3);

// ES6
let texto = `El ${animal} es de color ${color}`;
let suma = `El resultado es ${2 + 3}`;

Por otra parte, a diferencia de los string ES5, las nuevas líneas son parte de la cadena de
texto.
// ES5
var texto = "Esto es un texto que se\n
extiende múltiples líneas sin\n
necesidad de caracteres especiales";

// ES6
let texto = `Esto es un texto que se
extiende múltiples líneas sin
necesidad de caracteres especiales`;

Propiedades Abreviadas de Objeto


Otra de las novedades de ES2015 es la posibilidad de abreviar los literales de objeto, cuando
podemos asociar las propiedades de un objeto a variables del mismo nombre.

// ES5
function crearObjeto (color, ancho, alto) {
return {
color: color,
ancho: ancho,
alto: alto
};
}

// ES2015
function crearObjeto (color, ancho, alto) {
return { color, ancho, alto };
}

crearObjeto("red", "140px", "60px");


// → {
// → color: "red",
// → ancho: "140px",
// → alto: "60px"
// → }

Desestructuración
La desestructuración (destructuring) nos permite crear variables fácilmente a partir de un
objeto.

var persona = {
nombre: "Ariel",
edad: 34,
sexo: "Masculino"
}

// ES5
var nombre = [Link];
var edad = [Link];
var sexo = [Link];

// ES2015
let { nombre, edad, sexo } = persona;

nombre; // → "Ariel"
edad; // → 34
sexo; // → "Masculina"

Esto también funciona con los arrays:

let dias = ["lunes", "martes", "miercoles"];


let [primero, segundo, tercero] = dias;

primero; // → "lunes"
segundo; // → "martes"
tercero; // → "miercoles"

// también es posible omitir valores


let [primero,, tercero] = dias;

primero; // → "lunes"
tercero; // → "miercoles"

En el caso que tengamos objetos o arrays anidados, la desestructuración se vería asi:


let libro = {
titulo: "JavaScript Definitivo",
autor: {
nombre: "Ariel",
apellido: "Fuggini"
}
}

let { titulo, autor: { nombre, apellido } } = libro;

titulo; // → "JavaScript Definitivo"


nombre; // → "Ariel"
apellido; // → "Fuggini"

let dias = [31, 28, [31, 30]];


let [enero, febrero, [marzo, abril]] = dias;

enero; // → 31
febrero; // → 28
marzo; // → 31
abril; // → 30

Operador de Propagación
El operador de propagación (spread operator) permite expandir arrays y objetos, en lugares
donde se esperan otros valores, como pueden ser otros arrays u objetos, o argumentos de
funciones.
let array1 = [1, 2, 3];
let array2 = [...array1, 4, 5];

array2; // → [1, 2, 3, 4, 5]

let objeto1 = { x: 1, y: 2 };
let objeto2 = { ...objeto1, z: 3 };

objeto2; // → { x: 1, y: 2, z: 3 };

const sumar = (x, y, z) => x + y + z;

sumar(...array1); // → 6
// equivale a sumar(1, 2, 3);

Ese sencillo operador nos permite algunos usos bastante prácticos:

Clonar un array

var array1 = [1, 2, 3];

// ES5
var array2 = [Link]();

// ES6
var array2 = [...array1];

Concatenar arrays

var array1 = [1, 2, 3];


var array2 = [4, 5, 6];

// ES5
var array3 = [Link](array2);

// ES6
var array3 = [...array1, ...array2];
Clonar un objeto

var objeto1 = { a: 1, b: 2, c: 3 };

// ES5
function clonar (objeto) {
var copia = [Link]();
for (var propiedad in objeto) {
if ([Link](propiedad)) {
copia[propiedad] = objeto[propiedad];
}
}
return copia;
}
var objeto2 = clonar(objeto1);

// ES6
var objeto2 = { ...objeto1 };

Concatenar objetos

var objeto1 = { a: 1, b: 2 };
var objeto2 = { c: 3 };

// ES5
// Requiere crear otra función

// ES6
var objeto3 = { ...objeto1, ...objeto2 };

Parámetro Resto
El parámetro resto nos permite transformar un número indefinido de parámetros de
función en un array.
const prueba = (a, b, ...resto) => {
[Link](a);
[Link](b);
[Link](resto);
}

prueba(1, 2, 3, 4, 5);
// → 1
// → 2
// → [3, 4, 5]

Parámetros por Defecto


ES2015 nos permite asignarle a los parámetros de una función un valor por defecto, que será
utilizado en los casos en que al invocar la función el parámetro no reciba un valor, o bien
reciba undefined.

function suma (a = 0, b = 0) {
return a + b;
}

suma(1, 2); // → 3 (1 + 2)
suma(1); // → 1 (1 + 0)
suma(); // → 0 (0 + 0)
suma(4, undefined); // → 4 (4 + 0)
SOBRE EL AUTOR
Ariel Fuggini nació en 1985 en la Ciudad de Buenos Aires, Argentina.

Realizó estudios universitarios en Diseño Gráfico y Psicología. Sin embargo, su pasión


siempre fue la web.

A los 15 años comenzó a programar sus primeras páginas web como hobbie. A los 21
comenzó a hacerlo en forma profesional, y a los 23 fundó su propia agencia de diseño web,
que llevo adelante por varios años.

Ha capacitado a diseñadores y programadores Junior teniendo un impacto directo en sus


desarrollos profesionales, además de haber dado cursos presenciales de desarrollo web y
programación.

Colaboró en cientos de proyectos digitales como desarrollador frontend, full stack, diseñador
de UI, arquitecto de infraestructura cloud, entre otros, y ha trabajado tanto con startups
como con empresas establecidas de diversos países del mundo.

Actualmente se desempeña como desarrollador full stack para una empresa unicornio basada
en San Francisco, además de mentor y creador de contenidos a través de su sitio web,
[Link].

También podría gustarte