Hoisting lo que hace es que las variables y constantes suben al inicio del código, entonces existen para el compilador pero
pero no con su valor asignado, por lo que si se intenta acceder a ellas antes de ser declaradas, se obtendrá un valor undefined
console.log(x);
// Output: undefined
var x = 5;
console.log(x);
// Output: 5
Usar camelCase para nombrar variables y constantes ej: hoistedVariable son case-sensitive así que hoistedvariable no es lo mismo
let num = 10;
let texto = "Hola";
let esVerdadero = true;
let indefinido;
let nulo = null;
let persona = { nombre: "Juan", edad: 30 };
const simboloId = Symbol('id');
let bigNum = 9007199254740991n;
let persona = {
nombre: "Juan",
edad: 30,
casado: false
};
Un objeto en JavaScript es una colección de pares clave-valor. En este ejemplo, se crea un objeto llamado persona
con tres propiedades: nombre
, edad
y casado
.
console.log(persona.nombre); // Juan
console.log(persona['edad']); // 30
Las propiedades de un objeto se pueden acceder utilizando la notación de punto o la notación de corchetes.
let persona = {
nombre: "Juan",
edad: 30,
casado: false,
saludar: function() {
console.log("Hola, mi nombre es " + this.nombre);
}
};
persona.saludar(); // Hola, mi nombre es Juan
Los objetos en JavaScript pueden contener métodos, que son funciones asociadas al objeto. En este ejemplo, saludar
es un método de persona
que imprime un saludo.
function Animal(nombre) {
this.nombre = nombre;
}
Animal.prototype.saludar = function() {
console.log("Hola, soy un " + this.nombre);
};
let perro = new Animal("Perro");
perro.saludar(); // Hola, soy un Perro
Los objetos en JavaScript pueden heredar propiedades y métodos de otros objetos a través del prototipo. En este ejemplo, se define un constructor Animal
con un método saludar
que es heredado por el objeto perro
.
Cuando intentas acceder a una propiedad de un objeto, JavaScript primero busca esa propiedad en el objeto mismo. Si no la encuentra, busca en el prototipo del objeto y luego en el prototipo del prototipo, y así sucesivamente hasta llegar al prototipo null.
Ejemplo cuando hago Animal.prototype.nombreAnimal = function() {
console.log("Hola, soy " + this.nombreAnimal);
};
Lo que hago es cargarle al prototipo al animal el metodo no al objeto animal directamente. Ahorrando memoria porque evito duplicar metodos por cada instancia de animal.
let persona = { nombre: 'Juan', edad: 30 };
let numeros = [1, 2, 3, 4, 5];
let mensaje = 'Hola, mundo!';
let edad = 30;
let esMayor = true;
function saludar(nombre) { console.log('Hola, ' + nombre); }
let fecha = new Date();
let expresionRegular = /[a-z]+/;
throw new Error('Este es un error personalizado');
let raizCuadrada = Math.sqrt(16);
let personaJSON = '{"nombre": "Juan", "edad": 30}';
Puedes convertir un objeto JavaScript a una cadena JSON utilizando el método JSON.stringify():
persona = { nombre: "Juan", edad: 30 };
let personaJSON = JSON.stringify(persona);
console.log(personaJSON); // '{"nombre":"Juan","edad":30}'
typeof es un operador en JavaScript que se utiliza para obtener el tipo de datos de una variable o expresión.
let x = 10;
console.log(typeof x); // "number"
JavaScript realiza conversiones implícitas de tipos cuando se realiza una operación entre tipos de datos diferentes. Por ejemplo:
let x = 10 + "20"; // x es "1020" (string)
let y = "10" - 5; // y es 5 (number)
Se puede realizar conversión explícita utilizando funciones o operadores específicos:
parseInt()
y parseFloat()
: Convierten una cadena a un número entero o decimal, respectivamente. let num1 = parseInt("10"); // num1 es 10
let num2 = parseFloat("10.5"); // num2 es 10.5
String()
: Convierte un valor a una cadena de texto.Number()
: Convierte un valor a un número.Boolean()
: Convierte un valor a un booleano.La coerción de tipos es la conversión automática o implícita de valores de un tipo de datos a otro. JavaScript es un lenguaje de tipado débil y dinámico, lo que significa que los tipos de datos se convierten automáticamente según sea necesario durante la ejecución del programa. Puede convertir automáticamente los valores de un tipo a otro según sea necesario para completar una operación. Por ejemplo, en una operación de suma donde uno de los operandos es una cadena, JavaScript convertirá el otro operando a cadena y concatenará las cadenas en lugar de sumar los números.
Un array es una estructura de datos que se utiliza para almacenar una colección de elementos. Puedes inicializar un array con elementos predefinidos o crear un array vacío y agregar elementos a él dinámicamente.
Ejemplo:
let numeros = [1, 2, 3, 4, 5];
TypedArray es un tipo especial de array en JavaScript que proporciona un mecanismo eficiente para trabajar con datos binarios y de tipo específico. A diferencia de los arrays normales, los TypedArray están diseñados para contener elementos de un tipo específico y se utilizan principalmente en operaciones que requieren un acceso rápido a los datos binarios.
Ejemplo:
let numeros = new Uint8Array([1, 2, 3, 4, 5]);
El objeto Map es una estructura de datos que almacena pares clave-valor y mantiene el orden de inserción de las claves. Las claves de un mapa pueden ser de cualquier tipo, incluidos objetos y valores primitivos.
Ejemplo:
let mapa = new Map();
mapa.set("clave1", "valor1");
mapa.set("clave2", "valor2");
El objeto Set es una estructura de datos que almacena valores únicos de cualquier tipo. Los valores en un conjunto son únicos, lo que significa que no puede haber duplicados en el conjunto.
Ejemplo:
let conjunto = new Set();
conjunto.add("a");
conjunto.add("b");
conjunto.add("a"); // "a" ya existe en el conjunto
El objeto WeakMap es una colección de pares clave/valor en la que las claves son objetos y los valores pueden ser de cualquier tipo. A diferencia de un Map estándar, las claves en un WeakMap son débiles (weak), lo que significa que no evitan que los objetos utilizados como claves sean eliminados por el recolector de basura si no hay otras referencias a ellos fuera del WeakMap.
Ejemplo:
let weakMap = new WeakMap();
let key = {};
weakMap.set(key, "value");
Lo que hacen estos weakmap y weakset es que pueden ser borrados por el garbage collector cuando ya no son accesibles o referenciados por ninguna parte del código
Ejemplo con Weakmap vs Map
john = { name: "John" };
let weakMap = new WeakMap();
weakMap.set(john, "...");
john = null; // overwrite the reference
// john is removed from memory!
let john = { name: "John" };
let array = [ john ];
john = null; // overwrite the reference
// the object previously referenced by john is stored inside the array
// therefore it won't be garbage-collected
// we can get it as array[0]
El objeto WeakSet es una colección de objetos. A diferencia de Set, los objetos en un WeakSet son débiles (weak), lo que significa que si no hay otras referencias a un objeto almacenado en un WeakSet, el recolector de basura puede eliminar el objeto de la memoria.
Ejemplo:
let weakSet = new WeakSet();
let obj = {};
weakSet.add(obj);
==
)1 == '1'
devuelve true
porque JavaScript convierte automáticamente el string '1'
en el número 1
antes de realizar la comparación.===
)1 === '1'
devuelve false
porque los tipos de datos son diferentes (número vs string), incluso si los valores son iguales.En general, se recomienda utilizar la comparación de igualdad estricta (===
) en lugar de la comparación de igualdad débil (==
), ya que la igualdad estricta es más predecible y menos propensa a errores debido a las conversiones automáticas de tipo que realiza JavaScript en la igualdad débil.
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
console.log(-0 === +0); // true
console.log(Object.is(-0, +0)); // false
For in se utiliza para iterar sobre las propiedades de un objeto. For of se utiliza para iterar sobre los elementos de un objeto iterable como un array o un string.
La palabra clave break
se utiliza para salir de un bucle.
for (let i = 0; i < 10; i++) {
if (i === 5) {
break;
}
console.log(i);
}
// Salida: 0 1 2 3 4
La palabra clave continue
se utiliza para saltar a la siguiente iteración de un bucle.
for (let i = 0; i < 5; i++) {
if (i === 2) {
continue;
}
console.log(i);
}
// Salida: 0 1 3 4
Las declaraciones etiquetadas te permiten asociar una etiqueta a una declaración para controlar el flujo de ejecución.
outerloop: for (let i = 0; i < 3; i++) {
innerloop: for (let j = 0; j < 3; j++) {
console.log('i = ' + i + ', j = ' + j);
if (i === 1 && j === 1) {
break outerloop;
}
}
}
En este ejemplo, la etiqueta "outerloop" está asociada al bucle exterior y "innerloop" al bucle interior. La declaración break outerloop;
hace que se salga del bucle etiquetado como "outerloop", terminando ambos bucles.
El manejo de excepciones se utiliza para controlar errores que pueden ocurrir durante la ejecución de un programa, javascript creara un objeto error con dos propiedades nombre y mensaje.
try
: Define un bloque de código en el que pueden ocurrir errores.catch
: Define un bloque de código para manejar las excepciones lanzadas en el bloque try
.finally
: Define un bloque de código que se ejecutará siempre, independientemente de si se produce un error o no en el bloque try
.throw
: Lanza una excepción manualmente.
function validarEdad(edad) {
if (edad < 18) {
throw new Error("La edad debe ser mayor o igual a 18 años");
}
return "Puede ingresar";
}
try {
let resultado = validarEdad(16);
console.log(resultado);
} catch (error) {
console.error('Se produjo un error:', error.message);
} finally {
console.log('Este bloque siempre se ejecuta, independientemente de si se produjo un error o no');
}
Las declaraciones de funciones en JavaScript se realizan utilizando la palabra clave function
. Las funciones también se pueden definir guardando expresiones de función en una variable. Las funciones "arrow" se utilizan comúnmente de esta manera.
function saludar(nombre) {
return "¡Hola, " + nombre + "!";
}
let mensaje = saludar("John");
console.log(mensaje); // Salida: ¡Hola, John!
Cuando se define una función, aún no se ejecuta. Para llamar e invocar el código de una función, utiliza el nombre de la función seguido de paréntesis: nombreDeLaFuncion()
.
function suma(a, b) {
return a + b;
}
let resultado = suma(5, 3);
console.log(resultado); // Salida: 8
Los parámetros predeterminados te permiten especificar valores por defecto para los parámetros de una función en caso de que no se pase ningún argumento o si el argumento es undefined
. Esta característica fue introducida en ECMAScript 6 (ES6).
function saludar(nombre = "Invitado") {
console.log("Hola, " + nombre + "!");
}
saludar(); // Salida: Hola, Invitado!
saludar("Juan"); // Salida: Hola, Juan!
En el ejemplo anterior, la función saludar
tiene un parámetro predeterminado nombre
establecido en "Invitado"
. Si no se proporciona ningún argumento al llamar a saludar()
, utilizará el valor predeterminado. Si se proporciona un argumento, utilizará el valor proporcionado.
Los Rest Parameters en JavaScript permiten a una función aceptar un número variable de argumentos como un array, proporcionando una forma de representar una cantidad indefinida de parámetros como un solo parámetro. Esto es útil cuando queremos que una función acepte un número variable de argumentos sin tener que especificar cada uno de ellos en la definición de la función.
La sintaxis de Rest Parameters en JavaScript es utilizar tres puntos (`...`) seguidos del nombre que queremos darle al parámetro que recogerá el resto de los argumentos:
function nombreFuncion(parametro1, parametro2, ...restoDeParametros) {
// Cuerpo de la función
}
En este ejemplo, `parametro1` y `parametro2` son parámetros normales de la función, mientras que `restoDeParametros` es el Rest Parameter que recogerá el resto de los argumentos pasados a la función en forma de un array.
La sintaxis básica de una Arrow Function es:
let miFuncion = (param1, param2) => {
// Cuerpo de la función
};
Si el cuerpo de la función consiste en una sola expresión, puedes omitir las llaves y la palabra return
:
let cuadrado = (num) => num * num;
console.log(cuadrado(5)); // Salida: 25
Si la función no tiene parámetros o tiene solo un parámetro, puedes omitir los paréntesis alrededor de los parámetros:
let saludar = () => "Hola";
console.log(saludar()); // Salida: Hola
let duplicar = num => num * 2;
console.log(duplicar(3)); // Salida: 6
En las Arrow Functions, this
se mantiene del contexto léxico circundante:
function Persona() {
this.edad = 0;
setInterval(() => {
this.edad++; // `this` apunta al objeto Persona
console.log(this.edad);
}, 1000);
}
let p = new Persona();
Las Arrow Functions no pueden ser utilizadas como constructores para crear objetos y no tienen su propio this
.
() => expression
param => expression
(param) => expression
(param1, paramN) => expression
() => { statements }
param => { statements }
(param1, paramN) => { statements }
Las IIFE (Immediately Invoked Function Expressions) en JavaScript son funciones que se ejecutan inmediatamente después de ser definidas. Son útiles en situaciones donde necesitas ejecutar una función de forma inmediata y luego descartarla, lo que ayuda a evitar la contaminación del ámbito global y a mantener el código más organizado.
Sintaxis básica: La sintaxis de una IIFE (Immediately Invoked Function Expression) en JavaScript consiste en envolver una función entre paréntesis y luego llamarla inmediatamente añadiendo () al final. Esto hace que la función se ejecute automáticamente tan pronto como se define.
(function() {
// Código a ejecutar
})();
Uso de parámetros
(function(param1, param2) {
// Código a ejecutar con parámetros
})(valor1, valor2);
Evitar la contaminación del ámbito global
(function() {
var mensaje = "Hola, mundo!";
console.log(mensaje);
})();
// console.log(mensaje); // Esto dará un error porque `mensaje` está fuera de ámbito
Módulos
var modulo = (function() {
var privadoVariable = "Soy privado";
function privadoFuncion() {
return "También soy privado";
}
return {
publicoVariable: "Soy público",
publicoFuncion: function() {
return "También soy público";
}
};
})();
console.log(modulo.publicoVariable); // Salida: Soy público
console.log(modulo.publicoFuncion()); // Salida: También soy público
// console.log(modulo.privadoVariable); // Esto dará un error porque `privadoVariable` es privada
// console.log(modulo.privadoFuncion()); // Esto dará un error porque `privadoFuncion` es privada
Las IIFE son una herramienta útil en JavaScript para encapsular código y evitar la contaminación del ámbito global, lo que las hace especialmente útiles en aplicaciones más grandes y complejas.
El objeto arguments
en JavaScript es una variable local disponible dentro de todas las funciones que proporciona un conjunto de argumentos pasados a la función cuando es llamada. El objeto arguments
es similar a un array, pero no tiene todas las funcionalidades de un array (por ejemplo, no tiene métodos como map
o forEach
).
function suma() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(suma(1, 2, 3, 4, 5)); // Salida: 15
Número de argumentos
function numeroDeArgumentos() {
return arguments.length;
}
console.log(numeroDeArgumentos(1, 2, 3)); // Salida: 3
No es un array real
Aunque el objeto arguments
se comporta de manera similar a un array, no es un array real y no tiene todos los métodos de un array. Por ejemplo, no puedes utilizar métodos como map
o forEach
directamente en el objeto arguments
.
Contexto de ejecución
function ejemplo(a, b) {
console.log(arguments[0], arguments[1]);
a = 10;
b = 20;
console.log(arguments[0], arguments[1]);
}
ejemplo(1, 2);
// Salida:
// 1, 2
// 1, 2
El objeto arguments
puede ser útil cuando necesitas manejar un número variable de argumentos en una función o cuando no sabes de antemano cuántos argumentos serán pasados. Sin embargo, su uso se considera menos común en el desarrollo moderno de JavaScript, ya que existen alternativas más simples y seguras, como el uso de parámetros de función predeterminados o el uso de arrays reales para pasar argumentos.
La pila de funciones (Function Stack) en JavaScript se ejecuta de manera secuencial, de arriba hacia abajo. Esto significa que cuando se llama a una función, se añade al principio de la pila (arriba de todo) y se ejecuta antes que las funciones que ya estaban en la pila. Una vez que una función termina su ejecución, se elimina de la pila y el control vuelve a la función que estaba en la parte superior de la pila antes de que se llamara a la función actual. Por ejemplo si una función llama a otra función primero se ejecuta la que se llamó y después que esta termine se vuelve a la original que la llamó.
La recursión es un concepto en programación en el que una función se llama a sí misma para resolver un problema. La recursión se utiliza comúnmente en algoritmos que pueden dividirse en subproblemas más pequeños que son similares al problema original. La recursión se compone de dos partes: el caso base y el caso recursivo.
var recursionLimit = 0;
function r() {
recursionLimit++;
r();
}
r();
Un closure en JavaScript es una función que tiene acceso a variables en su ámbito externo, incluso después de que la función externa haya terminado de ejecutarse. En otras palabras, un closure recuerda el ámbito en el que se creó y puede acceder a las variables de ese ámbito incluso cuando la función se ejecuta en un contexto diferente.
Los closures son posibles en JavaScript debido al "lexical scoping", que determina el alcance de las variables en función de la estructura del código fuente. Cuando una función se define dentro de otra función, la función interna forma un closure sobre las variables de la función externa, lo que significa que retiene acceso a esas variables incluso después de que la función externa haya finalizado.
Los closures son útiles en muchos escenarios, como para crear funciones que actúan como contadores privados, para encapsular datos privados en módulos, para manejar eventos y devoluciones de llamada, entre otros.
En resumen, los closures en JavaScript permiten un manejo más flexible de las variables y el alcance de las funciones, lo que los hace una característica poderosa y versátil del lenguaje.
function contador() {
let count = 0;
return function() {
return ++count;
};
}
let incrementar = contador();
console.log(incrementar()); // 1
console.log(incrementar()); // 2
console.log(incrementar()); // 3
El "modo estricto" (strict mode) es una característica de JavaScript introducida en ECMAScript 5 que te permite escribir código JavaScript de manera más segura y con mejores prácticas. Cuando se activa el "modo estricto", se hacen algunas restricciones y cambios en el comportamiento normal de JavaScript.
Algunas de las características y usos del "modo estricto" incluyen:
with
.En resumen, el "modo estricto" es una herramienta útil para escribir código JavaScript más seguro y robusto, evitando errores comunes y aplicando mejores prácticas de programación. Se recomienda utilizarlo en todos los nuevos proyectos y al actualizar código existente para mejorar su calidad y mantenibilidad.
El keyword this
en JavaScript se refiere al objeto al que pertenece en un determinado contexto. El valor de this
depende de cómo se llama a la función y dónde se encuentra la llamada a la función.
this
se refiere al objeto global en el navegador (window
en un navegador web) o al objeto global en Node.js (global
en Node.js).this
se refiere al objeto que posee el método.this
se refiere al objeto global (o undefined
en modo estricto).
let objeto = {
nombre: 'Juan',
saludar: function() {
console.log('Hola, mi nombre es ' + this.nombre);
}
};
objeto.saludar(); // Hola, mi nombre es Juan
let saludarFuncion = objeto.saludar;
saludarFuncion(); // TypeError en modo estricto, de lo contrario: Hola, mi nombre es undefined o Hola, mi nombre es [nombre global]
this
se refiere al elemento en sí en un manejador de eventos en un elemento HTML.this
se mantiene del ámbito exterior al que pertenece la función flecha, en lugar de ser dinámico como en las funciones regulares.
let objeto = {
nombre: 'María',
saludar: function() {
setTimeout(() => {
console.log('Hola, mi nombre es ' + this.nombre);
}, 1000);
}
};
objeto.saludar(); // Hola, mi nombre es María después de 1 segundo
Entender cómo funciona this
es importante para evitar errores y utilizarlo correctamente en diferentes situaciones en JavaScript.
In an object method, this refers to the object
Alone, this refers to the global object
In a function, this refers to the global object
In a function, in strict mode, this is undefined
In an event, this refers to the element that received the event
Methods like call(), apply(), and bind() can refer this to any object
Fucntion Borrowing consiste en tomar prestada una función de otro objeto y utilizarla en el contexto de un objeto diferente. Esto se puede hacer utilizando los métodos call()
y apply()
en JavaScript. Es medio controversial "Function borrowing is usually just a workaround for poor initial design."
let obj1 = {
nombre: 'Juan',
saludar: function() {
console.log('Hola, mi nombre es ' + this.nombre);
}
};
let obj2 = {
nombre: 'María'
};
obj1.saludar(); // Hola, mi nombre es Juan
// Usando la función de obj1 en obj2
obj1.saludar.call(obj2); // Hola, mi nombre es María
Explicit Binding es una técnica en JavaScript para forzar a una función a utilizar/asociar un objeto específico como su contexto de this
. Esto se puede hacer utilizando los métodos call()
lo pide separado por comas, apply()
lo pide como un arreglo de los parámetros o bind()
te crea una función nueva con el contexto nuevo en JavaScript.
const persona = {
nombre: 'Juan',
};
const otraPersona = {
nombre: 'María'
};
function saludar(likes, dislikes) {
console.log('Hola, mi nombre es ' + this.nombre + y tengo ' + likes + ' likes y ' + dislikes + ' dislikes');
}
console.log(saludar.call(persona, 10, 5)); // Hola, mi nombre es Juan y tengo 10 likes y 5 dislikes
console.log(saludar.apply(otraPersona, [20, 10])); // Hola, mi nombre es María y tengo 20 likes y 10 dislikes
const nuevaFuncion = saludar.bind(persona);
console.log(nuevaFuncion(15, 5)); // Hola, mi nombre es Juan y tengo 15 likes y 5 dislikes
La programación asíncrona es una técnica que permite que tu programa inicie una tarea potencialmente de larga duración y aún así pueda responder a otros eventos mientras esa tarea se ejecuta, en lugar de tener que esperar hasta que esa tarea haya terminado. Una vez que esa tarea ha terminado, tu programa recibe el resultado.
Muchas funciones proporcionadas por los navegadores, especialmente las más interesantes, pueden llevar mucho tiempo y, por lo tanto, son asíncronas. Por ejemplo:
Hacer solicitudes HTTP utilizando fetch()
Acceder a la cámara o al micrófono de un usuario utilizando getUserMedia()
Pedir a un usuario que seleccione archivos utilizando showOpenFilePicker()
Hay varias formas de lograr la asincronía en JavaScript:
function doStep1(init, callback) {
const result = init + 1;
callback(result);
}
function doStep2(init, callback) {
const result = init + 2;
callback(result);
}
function doStep3(init, callback) {
const result = init + 3;
callback(result);
}
function doOperation() {
doStep1(0, (result1) => {
doStep2(result1, (result2) => {
doStep3(result2, (result3) => {
console.log(`result: ${result3}`);
});
});
});
}
doOperation();
function hacerAlgoAsincrono() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('Operación asincrónica completada');
resolve();
}, 1000);
});
}
console.log('Comenzando operación asincrónica');
hacerAlgoAsincrono().then(function() {
console.log('Continuando con el flujo de trabajo');
});
async function hacerAlgoAsincrono() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('Operación asincrónica completada');
resolve();
}, 1000);
});
}
console.log('Comenzando operación asincrónica');
async function ejecutar() {
await hacerAlgoAsincrono();
console.log('Continuando con el flujo de trabajo');
}
ejecutar();
En resumen, JavaScript ofrece varias formas de trabajar de manera asíncrona, lo que es fundamental para construir aplicaciones web interactivas y eficientes. La elección de la técnica adecuada depende del caso de uso específico y de las preferencias de estilo de codificación.
La función setTimeout
se utiliza para ejecutar una función o un fragmento de código una vez después de un período de tiempo especificado.
setTimeout(function() {
console.log('Hola, mundo!');
}, 1000); // Ejecutar después de 1 segundo
La función setInterval
se utiliza para ejecutar una función o un fragmento de código repetidamente cada cierto período de tiempo especificado.
setInterval(function() {
console.log('Hola, mundo!');
}, 1000); // Ejecutar cada 1 segundo
Es importante tener en cuenta que tanto setTimeout
como setInterval
son funciones asíncronas y no detienen la ejecución del resto del código. Además, ambas funciones devuelven un identificador que puede usarse para cancelar la ejecución futura de la función con clearTimeout
(para setTimeout
) o clearInterval
(para setInterval
).
XMLHttpRequest es un objeto en JavaScript que proporciona funcionalidades para realizar solicitudes HTTP de forma asíncrona.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://ejemplo.com/api/data', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.send();
fetch es una API moderna para realizar solicitudes HTTP que proporciona una interfaz más limpia y promesas para trabajar de manera asíncrona.
fetch('https://ejemplo.com/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Para declarar una clase en JavaScript, utilizamos la palabra clave class
, seguida del nombre de la clase. Dentro de la clase, definimos métodos utilizando la sintaxis de funciones normales.
class Persona {
constructor(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}
saludar() {
console.log(`Hola, mi nombre es ${this.nombre} y tengo ${this.edad} años.`);
}
}
Para crear un objeto de una clase, utilizamos la palabra clave new
seguida del nombre de la clase y los argumentos necesarios para el constructor, si lo tiene.
let persona1 = new Persona('Juan', 30);
let persona2 = new Persona('María', 25);
Las clases en JavaScript también admiten la herencia. Para heredar de una clase base, utilizamos la palabra clave extends
seguida del nombre de la clase base.
class Estudiante extends Persona {
constructor(nombre, edad, curso) {
super(nombre, edad);
this.curso = curso;
}
estudiar() {
console.log(`${this.nombre} está estudiando ${this.curso}.`);
}
}
let estudiante1 = new Estudiante('Pedro', 20, 'Matemáticas');
Los iteradores son objetos que permiten recorrer secuencias de datos, como arrays, cadenas (strings) o cualquier objeto con una estructura similar a una colección.
let arr = [1, 2, 3];
let iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
Los generadores son funciones especiales que pueden ser pausadas y luego reanudadas. Se declaran utilizando la palabra clave function*
y utilizan la palabra clave yield
para pausar la ejecución y devolver un valor.
function* generateNumbers() {
yield 1;
yield 2;
yield 3;
}
let generator = generateNumbers();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
Los generadores son útiles cuando se necesitan secuencias de valores que pueden ser generados de manera perezosa (lazy) o cuando se necesita un control más fino sobre la generación de valores en una secuencia. Los iteradores y generadores son características poderosas de JavaScript que pueden mejorar la legibilidad y la eficiencia del código cuando se utilizan correctamente.
Para exportar variables, funciones o clases desde un módulo, utilizamos la palabra clave export
. Podemos exportar elementos individualmente o usar la declaración export default
para exportar un elemento por defecto.
// En el archivo modulo.js
export const PI = 3.141592;
export function double(number) {
return number * 2;
}
export default function sayHello(name) {
console.log(`Hello, ${name}!`);
}
Para importar elementos de un módulo en otro, utilizamos la palabra clave import
. Podemos importar elementos individualmente o importar todo un módulo con la declaración import * as nombre from 'ruta'
.
// En otro archivo
import { PI, double } from './modulo.js';
import sayHello from './modulo.js';
console.log(PI); // 3.141592
console.log(double(5)); // 10
sayHello('John'); // Hello, John!
También podemos exportar e importar todo un módulo utilizando la declaración export * from 'ruta'
para exportar y import * as nombre from 'ruta'
para importar.
// En el archivo modulo.js
function greet(name) {
console.log(`Greetings, ${name}!`);
}
export { greet };
// En otro archivo
import * as modulo from './modulo.js';
modulo.greet('Alice'); // Greetings, Alice!
Los módulos en JavaScript nos permiten estructurar nuestro código de manera modular y reutilizable, lo que facilita el mantenimiento y la colaboración en proyectos más grandes. Es importante tener en cuenta que los módulos de JavaScript están estandarizados en ECMAScript 6 (ES6) y son ampliamente compatibles en navegadores modernos y entornos Node.js.
Las Chrome DevTools son un conjunto de herramientas de desarrollo integradas en el navegador Google Chrome que te permiten depurar, perfilar y editar sitios web y aplicaciones web directamente desde el navegador. Estas herramientas son muy útiles para los desarrolladores web, ya que proporcionan una variedad de funciones para mejorar el proceso de desarrollo y depuración de código JavaScript.
Las Chrome DevTools ofrecen muchas más funciones y herramientas que las mencionadas aquí, pero estas son algunas de las más relevantes para trabajar con JavaScript. Puedes acceder a las Chrome DevTools en Chrome haciendo clic con el botón derecho en cualquier parte de una página web y seleccionando "Inspeccionar" o utilizando el atajo de teclado Ctrl+Shift+I
(Windows/Linux) o Cmd+Opt+I
(Mac).
querySelector
El método querySelector
es una función poderosa en JavaScript que se utiliza para seleccionar elementos del DOM (Document Object Model) utilizando selectores CSS. Permite buscar y obtener el primer elemento que coincide con el selector especificado.
element = document.querySelector(selector);
selector
: Un string que representa uno o más selectores CSS que se usan para encontrar el elemento correspondiente en el DOM.var element = document.querySelector("#miId");
console.log(element); // Devuelve el elemento con id="miId"
var element = document.querySelector(".miClase");
console.log(element); // Devuelve el primer elemento con class="miClase"
var element = document.querySelector("p");
console.log(element); // Devuelve el primer <p> elemento
var element = document.querySelector("div.miClase #miId");
console.log(element); // Devuelve el elemento con id="miId" que está dentro de un <div> con class="miClase"
var element = document.querySelector("input[type='text']");
console.log(element); // Devuelve el primer <input> elemento con type="text"
querySelector
solo devuelve el primer elemento que coincide con el selector especificado. Si necesitas obtener todos los elementos que coinciden, puedes usar document.querySelectorAll(selector)
.
addEventListener
es un método en JavaScript que permite añadir un evento a un elemento del DOM (Document Object Model). Este método es fundamental para crear interactividad en las páginas web.
element.addEventListener(event, function, useCapture);
document.getElementById('myButton').addEventListener('click', function() {
alert('Button was clicked!');
});
document
es un objeto global que representa el documento HTML o XML cargado en el navegador. Proporciona varias propiedades y métodos para acceder y manipular el contenido y estructura del documento.
let element = document.getElementById('myElement');
element.style.color = 'red';
Los bundlers son herramientas que toman módulos de código (JavaScript, CSS, imágenes, etc.) y los combinan en un único archivo o en unos pocos archivos, optimizados para el navegador. Esto mejora la eficiencia del sitio web, reduciendo el número de solicitudes HTTP y optimizando el rendimiento.
Una herramienta muy flexible y poderosa que permite gestionar, empaquetar y optimizar los módulos. Soporta loaders y plugins para transformar y optimizar diferentes tipos de archivos.
// webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
};
Un bundler sencillo y rápido que requiere poca configuración. Detecta automáticamente los diferentes tipos de archivos y los gestiona adecuadamente.
parcel index.html
Enfocado en la construcción de bibliotecas JavaScript, Rollup crea paquetes más pequeños y eficientes utilizando la sintaxis de módulos ES6.
// rollup.config.js
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import babel from '@rollup/plugin-babel';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'iife',
name: 'MyBundle'
},
plugins: [
resolve(),
commonjs(),
babel({ babelHelpers: 'bundled' })
]
};
Cada uno de estos bundlers tiene sus propias ventajas y desventajas, y la elección depende de las necesidades específicas del proyecto.