JS Flashcards

(34 cards)

1
Q

¿Cuál es la diferencia entre let, const y var en JavaScript?

A
  • var:
    • Declaración antigua (antes de ES6).
    • Tiene scope de función (no respeta el bloque).
    • Se puede redeclarar y reasignar.
    • Sus variables son hoisted, pero inicializadas con undefined.
      -el var tiene una escopeta que apunta a una fundicion, y esta hosteado y se va para arriba
  • let:
    • Introducido en ES6.
    • Tiene scope de bloque (respeta {}).
    • No se puede redeclarar, pero sí reasignar.
    • También es hoisted, pero no accesible antes de la declaración (temporal dead zone).
      console.log(miVariable); // ReferenceError: Cannot access ‘miVariable’ before initialization
      let miVariable = 10;
      Leticia tiene una escopeta que le dispara a un bloque de hormigon y esta hosteada en una nube
  • const:
    • Introducido en ES6.
    • Tiene scope de bloque.
    • No se puede redeclarar ni reasignar.
    • Las constantes referenciales (objetos/arrays) pueden mutar su contenido, pero no el valor de referencia.
      constanza tiene una escopeta que tambien le dispara a un bloque de hormigon y hay un referí que la frena y se clona

Resumen rápido:
- Usa let para variables que cambian.
- Usa const para valores constantes o referencias inmutables.
- Evita var en proyectos modernos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

¿Cómo se utiliza el método filter() en un array en JavaScript?

A

hay un filtro de agua que tiene a un elementor, que tiene un indice de un libro y hace una fila con otros elementors

  • Descripción:
    El método filter() crea un nuevo array con los elementos que cumplen una condición especificada en una función de callback.
  • Sintaxis:
    javascript
    array.filter(callback(element, index, array), thisArg);

    • callback: Una función que se ejecuta para cada elemento del array.
      • element: El elemento actual.
      • index (opcional): El índice del elemento actual.
      • array (opcional): El array sobre el que se está iterando.
    • thisArg (opcional): Valor a usar como this dentro del callback.
  • Ejemplo básico:
    Filtrar números mayores a 5:
    javascript
    const numeros = [1, 4, 6, 8, 3];
    const mayoresA5 = numeros.filter(num => num > 5);
    console.log(mayoresA5); // [6, 8]
  • Ejemplo con objetos:
    Filtrar productos con precio mayor a $50:
    ```javascript
    const productos = [
    { nombre: “Laptop”, precio: 1000 },
    { nombre: “Mouse”, precio: 20 },
    { nombre: “Teclado”, precio: 50 },
    ];const productosCaros = productos.filter(producto => producto.precio > 50);
    console.log(productosCaros);
    // [{ nombre: “Laptop”, precio: 1000 }]
    ```
  • Nota importante:
    filter() no modifica el array original. Devuelve un nuevo array.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Explica cómo funciona el mecanismo de hoisting en JavaScript.

A

    • ¿Qué es el hoisting?
      Es un comportamiento de JavaScript donde las declaraciones de variables, funciones o clases se “elevan” al principio de su SCOPE ámbito (función o script) durante la fase de compilación.
  • Cómo funciona:
    • Variables con var:
      Solo se eleva la declaración, no la asignación.
      javascript
      console.log(miVar); // undefined
      var miVar = 5;

      Internamente, JavaScript lo interpreta así:
      javascript
      var miVar;
      console.log(miVar); // undefined
      miVar = 5;
    • Variables con let y const:
      También son elevadas, pero permanecen en la Temporal Dead Zone (TDZ) hasta que se ejecuta su declaración.
      javascript
      console.log(miLet); // ReferenceError
      let miLet = 10;
    • Funciones declarativas:
      Las declaraciones completas se elevan, por lo que puedes usarlas antes de definirlas.
      javascript
      saludar(); // "Hola"
      function saludar() {
        console.log("Hola");
      }
    • Funciones como expresiones (var):
      Solo se eleva la declaración, no la asignación.
      javascript
      console.log(saludar); // undefined
      var saludar = function () {
        console.log("Hola");
      };
    • Clases:
      Son elevadas, pero no puedes acceder a ellas antes de declararlas. Esto genera un ReferenceError.
      javascript
      const obj = new MiClase(); // ReferenceError
      class MiClase {}
  • Resumen:
    • var → Se eleva con valor undefined.
    • let y const → Se elevan, pero están en la TDZ.
    • Declaraciones de funciones → Se elevan completas.
    • Clases → Se elevan, pero no se pueden usar antes de declararlas.

¿Te gustaría añadir más ejemplos o explicaciones? 😊

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

¿Qué es una IIFE (Immediately Invoked Function Expression) en JavaScript?

A
  • Definición:
    Una IIFE es una función en JavaScript que se declara y se ejecuta inmediatamente después de su definición.
  • Sintaxis:
    Se envuelve la función en paréntesis para convertirla en una expresión, seguida de paréntesis adicionales para ejecutarla:
    javascript
    (function () {
      // Código aquí
    })();
  • Ejemplo básico:
    javascript
    (function () {
      console.log("Esto es una IIFE");
    })();
    // Salida: Esto es una IIFE
  • Con parámetros:
    Puedes pasar argumentos a una IIFE:
    javascript
    (function (nombre) {
      console.log(`Hola, ${nombre}`);
    })("Juan");
    // Salida: Hola, Juan
  • ¿Para qué se usa?
    • Crear un ámbito privado y evitar contaminar el ámbito global.
    • Encapsular variables y protegerlas de accesos externos.
    • Ejecutar código una sola vez, como inicializadores.
  • Ejemplo práctico:
    Crear una variable privada:
    ```javascript
    const contador = (function () {
    let count = 0;
    return {
    incrementar: function () {
    count++;
    console.log(count);
    },
    reiniciar: function () {
    count = 0;
    console.log(“Reiniciado”);
    },
    };
    })();contador.incrementar(); // 1
    contador.incrementar(); // 2
    contador.reiniciar(); // Reiniciado
    ```
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

¿Cómo funciona el método reduce() en arrays en JavaScript?

A

Jorge Sanier tiene un reduce fat fast, dentro tiene un acumulador de porquerias, con un elementor, que tiene un indice en la mano y una fila de elementors.
todos se apilan sobre el acumulador.

  • Descripción:
    El método reduce() ejecuta una función de callback sobre cada elemento de un array, acumulando un único valor final.
  • Sintaxis:
    javascript
    array.reduce(callback(acumulador, elemento, indice, array), valorInicial);
    • callback: Función que se ejecuta en cada elemento del array.
      • acumulador: El valor acumulado (resultado parcial).
      • elemento: El elemento actual del array.
      • indice (opcional): Índice del elemento actual.
      • array (opcional): El array sobre el que se está iterando.
    • valorInicial (opcional): Valor inicial del acumulador. Si no se especifica, se usa el primer elemento del array.
  • Ejemplo básico:
    Sumar todos los números de un array:
    javascript
    const numeros = [1, 2, 3, 4];
    const suma = numeros.reduce((acumulador, num) => acumulador + num, 0);
    console.log(suma); // 10
  • Ejemplo con objetos:
    Calcular el total de precios:
    ```javascript
    const productos = [
    { nombre: “Laptop”, precio: 1000 },
    { nombre: “Mouse”, precio: 20 },
    { nombre: “Teclado”, precio: 50 },
    ];const total = productos.reduce((acumulador, producto) => acumulador + producto.precio, 0);
    console.log(total); // 1070
    ```
  • Ejemplo sin valorInicial:
    Si no defines un valor inicial, el primer elemento se usa como acumulador y la iteración comienza desde el segundo elemento:
    javascript
    const numeros = [1, 2, 3, 4];
    const suma = numeros.reduce((acumulador, num) => acumulador + num);
    console.log(suma); // 10
  • Notas importantes:
    • Es útil para operaciones acumulativas como sumar, concatenar o transformar estructuras de datos.
    • reduce() no modifica el array original.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Explica qué es el spread operator y proporciona un ejemplo.

A

Aquí tienes la tarjeta sobre el spread operator:

  • ¿Qué es el spread operator?
    El spread operator (...) es una sintaxis de JavaScript que permite expandir o descomponer elementos de un iterable (como un array o un objeto) en elementos individuales.
  • Usos comunes del spread operator:
    • En arrays: Expande los elementos de un array dentro de otro array o en funciones.
    • En objetos: Copia las propiedades de un objeto a otro.
  • Sintaxis:
    javascript
    const nuevoArray = [...array];
    const nuevoObjeto = { ...objeto };

Ejemplos:

  1. En arrays:
    • Unir dos arrays:
      javascript
      const numeros = [1, 2, 3];
      const masNumeros = [4, 5, 6];
      const todosNumeros = [...numeros, ...masNumeros];
      console.log(todosNumeros); // [1, 2, 3, 4, 5, 6]
    • Copiar un array:
      javascript
      const original = [1, 2, 3];
      const copia = [...original];
      console.log(copia); // [1, 2, 3]
  2. En objetos:
    • Copiar un objeto:
      javascript
      const persona = { nombre: "Juan", edad: 30 };
      const personaCopiada = { ...persona };
      console.log(personaCopiada); // { nombre: "Juan", edad: 30 }
    • Modificar un objeto al copiarlo:
      javascript
      const persona = { nombre: "Juan", edad: 30 };
      const personaActualizada = { ...persona, edad: 31 };
      console.log(personaActualizada); // { nombre: "Juan", edad: 31 }
  3. En funciones (pasar elementos de un array como argumentos):
    javascript
    const numeros = [1, 2, 3];
    const suma = (a, b, c) => a + b + c;
    console.log(suma(...numeros)); // 6

Resumen:
El spread operator ... es muy útil para copiar, combinar o pasar elementos de arrays u objetos de manera eficiente.

¿Te gustaría algún ejemplo adicional o explicación más detallada? 😊

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Copia superficial (Shallow Copy)

A

Cuando usas el spread operator, se copian las propiedades primitivas (como string, number, boolean, etc.), pero si alguna propiedad es un objeto o un array, solo se copia la referencia a ese objeto, no el objeto en sí

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Copia profunda (Deep Copy):

A

Si deseas hacer una copia completa (profunda) del objeto, donde también se copien los objetos o arrays internos, necesitarías usar una técnica adicional, como la serialización JSON o una función personalizada.

JSON.parse(JSON.stringify()): Fácil y rápido, pero limitado a tipos serializables y sin referencias circulares.

Recursión manual: Muy flexible y personalizable.

Lodash cloneDeep(): Completo y optimizado para casos complejos.

structuredClone(): Solución nativa en navegadores modernos, eficiente y compatible con tipos complejos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

¿Cómo implementarías una función para clonar objetos en JavaScript?

A

Para clonar un objeto en JavaScript, existen varias formas dependiendo de si quieres una copia superficial o una copia profunda. A continuación se presentan ambas implementaciones:

  1. Copia Superficial:

Una copia superficial se puede hacer utilizando el spread operator (...) o Object.assign(). Ambos crean una nueva referencia para el objeto, pero las propiedades de tipo objeto siguen apuntando a la misma referencia en memoria.

Usando el spread operator:

```javascript
function clonarObjetoSuperficial(obj) {
return { …obj };
}

const original = { nombre: “Juan”, direccion: { ciudad: “Madrid” } };
const clon = clonarObjetoSuperficial(original);

clon.direccion.ciudad = “Barcelona”;
console.log(original.direccion.ciudad); // “Barcelona” (se afecta el objeto original)
console.log(clon.direccion.ciudad); // “Barcelona”
~~~

Usando Object.assign():

```javascript
function clonarObjetoSuperficial(obj) {
return Object.assign({}, obj);
}

const original = { nombre: “Juan”, direccion: { ciudad: “Madrid” } };
const clon = clonarObjetoSuperficial(original);

clon.direccion.ciudad = “Barcelona”;
console.log(original.direccion.ciudad); // “Barcelona” (se afecta el objeto original)
console.log(clon.direccion.ciudad); // “Barcelona”
~~~

  1. Copia Profunda:

Para hacer una copia profunda, donde las propiedades internas (objetos, arrays) también se copian de forma independiente, puedes utilizar métodos como la serialización JSON.parse()/JSON.stringify(), recursión manual o librerías externas.

Usando JSON.parse() y JSON.stringify():

```javascript
function clonarObjetoProfundo(obj) {
return JSON.parse(JSON.stringify(obj));
}

const original = { nombre: “Juan”, direccion: { ciudad: “Madrid” } };
const clon = clonarObjetoProfundo(original);

clon.direccion.ciudad = “Barcelona”;
console.log(original.direccion.ciudad); // “Madrid” (el objeto original no se afecta)
console.log(clon.direccion.ciudad); // “Barcelona”
~~~

Usando recursión manual (función personalizada):

```javascript
function clonarObjetoProfundo(obj) {
if (obj === null || typeof obj !== ‘object’) {
return obj; // Si no es un objeto, devuelve el valor.
}

const clon = Array.isArray(obj) ? [] : {}; // Crea un array o un objeto según corresponda.

for (const clave in obj) {
if (obj.hasOwnProperty(clave)) {
clon[clave] = clonarObjetoProfundo(obj[clave]); // Recursión
}
}

return clon;
}

const original = { nombre: “Juan”, direccion: { ciudad: “Madrid” } };
const clon = clonarObjetoProfundo(original);

clon.direccion.ciudad = “Barcelona”;
console.log(original.direccion.ciudad); // “Madrid” (el objeto original no se afecta)
console.log(clon.direccion.ciudad); // “Barcelona”
~~~

Resumen:

  • Copia superficial: Utiliza el spread operator ({...obj}) o Object.assign() para clonar el objeto, pero solo las referencias de los objetos internos son copiadas.
  • Copia profunda: Utiliza JSON.parse()/JSON.stringify() para objetos simples, o una función recursiva para manejar objetos más complejos, garantizando que los objetos internos también se clonen.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

¿Qué es la programación asíncrona y cómo se maneja en JavaScript?

A

Programación asíncrona:
Es un enfoque en el que las operaciones no bloquean la ejecución del código. Permite que otras tareas se realicen mientras una operación, como una solicitud a un servidor o la lectura de un archivo, está en progreso.

  • Cómo se maneja en JavaScript:
    • Callbacks: Funciones que se ejecutan cuando una tarea asíncrona termina.
    • Promises: Objetos que representan el resultado de una operación asíncrona. Pueden estar en tres estados: pendiente, resuelta o rechazada.
    • Async/Await: Sintaxis que permite escribir código asíncrono de manera más fácil y similar al código síncrono.

Ejemplo con async/await:

```javascript
async function obtenerDatos() {
let respuesta = await fetch(‘https://api.example.com/datos’);
let datos = await respuesta.json();
console.log(datos);
}

obtenerDatos();
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Explica qué son los callbacks, las promesas y el async/await en JavaScript.

A
  1. Callbacks:
    Un callback es una función que se pasa como argumento a otra función y se ejecuta cuando la tarea asíncrona termina. Los callbacks pueden ser difíciles de manejar si se anidan varios, lo que se conoce como “callback hell”.Ejemplo de callback:
    ```javascript
    function tareaAsincrona(callback) {
    setTimeout(() => {
    console.log(“Tarea completada”);
    callback(); // Llamada al callback
    }, 1000);
    }tareaAsincrona(() => {
    console.log(“Callback ejecutado”);
    });
    ```
  2. Promesas:
    Una promesa es un objeto que representa el resultado de una operación asíncrona. Tiene tres estados posibles:
    • Pendiente: La operación aún no ha terminado.
    • Resuelta (Fulfilled): La operación se completó correctamente.
    • Rechazada (Rejected): La operación falló.
    Las promesas se manejan usando .then() para el resultado exitoso y .catch() para errores.Ejemplo de promesa:
    ```javascript
    function tareaAsincrona() {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    let exito = true;
    if (exito) {
    resolve(“Tarea completada”);
    } else {
    reject(“Error en la tarea”);
    }
    }, 1000);
    });
    }tareaAsincrona()
    .then(result => console.log(result))
    .catch(error => console.log(error));
    ```
  3. Async/Await:
    async/await es una sintaxis más moderna para manejar operaciones asíncronas. async marca una función como asíncrona y permite el uso de await dentro de esa función. await espera a que una promesa se resuelva antes de continuar con la ejecución.Ejemplo con async/await:
    ```javascript
    async function tareaAsincrona() {
    let resultado = await new Promise((resolve, reject) => {
    setTimeout(() => resolve(“Tarea completada”), 1000);
    });
    console.log(resultado); // Espera a que la promesa se resuelva
    }tareaAsincrona();
    ```

Resumen:
- Callbacks: Funciones pasadas como argumentos y ejecutadas cuando se completa la tarea asíncrona.
- Promesas: Representan el resultado de una operación asíncrona, con tres estados: pendiente, resuelta o rechazada.
- Async/Await: Sintaxis que permite trabajar con promesas de manera más clara, evitando el anidamiento de callbacks.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

¿Qué son los módulos de ES6 y cómo se configuran?

A

Los módulos de ES6 (ECMAScript 6) permiten dividir el código JavaScript en archivos separados, lo que facilita la organización, reutilización y mantenimiento del código. Los módulos permiten importar y exportar funciones, objetos y valores entre diferentes archivos.

Principales características de los módulos de ES6:
- Los módulos son escritos en archivos separados (con extensión .js o .mjs).
- Usan las palabras clave import y export para intercambiar funcionalidades entre archivos.
- Los módulos son estáticos, lo que significa que las dependencias se resuelven en tiempo de compilación.

Cómo se configuran:

  1. Exportar elementos de un módulo:

Puedes exportar variables, funciones o clases de un archivo para que puedan ser importadas por otros módulos.

  • Exportación nombrada: Exportas múltiples elementos de un módulo de forma individual.
    javascript
    // archivo1.js
    export const nombre = "Juan";
    export function saludar() {
      console.log("Hola, " + nombre);
    }
  • Exportación por defecto: Exportas un único valor o función como la exportación principal.
    javascript
    // archivo2.js
    export default function() {
      console.log("Esta es una función por defecto");
    }
  1. Importar elementos de un módulo:
  • Importación nombrada: Importas elementos específicos desde un módulo.
    javascript
    // archivo3.js
    import { nombre, saludar } from './archivo1.js';
    saludar();  // Salida: "Hola, Juan"
  • Importación por defecto: Importas el valor o función exportada por defecto.
    javascript
    // archivo4.js
    import saludarDefault from './archivo2.js';
    saludarDefault();  // Salida: "Esta es una función por defecto"
  1. Usar módulos en el navegador o Node.js:
  • En el navegador, debes usar el atributo type="module" en la etiqueta <script>:
    html
    <script type="module" src="app.js"></script>
  • En Node.js:
    • Desde Node.js versión 12, puedes usar módulos de ES6 de manera nativa con el archivo .mjs o configurando "type": "module" en el archivo package.json.

Resumen:
- Módulos de ES6: Son archivos de JavaScript que permiten exportar e importar funcionalidades para mejorar la organización del código.
- Exportación: Se usa export para compartir elementos (nombrados o por defecto).
- Importación: Se usa import para traer esos elementos en otros archivos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

¿Cómo implementas un temporizador con setTimeout y setInterval?

A

setTimeout() ejecuta una función después de un tiempo específico (en milisegundos). Se utiliza para ejecutar una acción una sola vez después de un retraso.

let temporizador = setTimeout(() => {
console.log(“Esto no se ejecutará”);
}, 3000);
// Cancelar el temporizador antes de que se ejecute
clearTimeout(temporizador);

setInterval() ejecuta una función repetidamente, con un intervalo de tiempo entre cada ejecución.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

¿Cuál es la diferencia entre call, apply y bind en JavaScript?

A

call():
- call() permite invocar una función con un valor específico para this y los argumentos pasados de manera individual.
- La sintaxis es:
func.call(thisValue, arg1, arg2, ...)

Ejemplo:

```javascript
function saludar() {
console.log(Hola, mi nombre es ${this.nombre});
}

const persona = { nombre: ‘Juan’ };

saludar.call(persona); // “Hola, mi nombre es Juan”
~~~

apply():
- apply() es similar a call, pero los argumentos se pasan como un array o array-like.
- La sintaxis es:
func.apply(thisValue, [arg1, arg2, ...])

Ejemplo:

```javascript
function saludar(mensaje) {
console.log(${mensaje}, mi nombre es ${this.nombre});
}

const persona = { nombre: ‘Juan’ };

saludar.apply(persona, [‘Hola’]); // “Hola, mi nombre es Juan”
~~~

bind():
- bind() crea una nueva función con un this específico y, opcionalmente, algunos argumentos predefinidos. Esta nueva función puede ser invocada más tarde.
- La sintaxis es:
const nuevaFuncion = func.bind(thisValue, arg1, arg2, ...)

Ejemplo:

```javascript
function saludar(mensaje) {
console.log(${mensaje}, mi nombre es ${this.nombre});
}

const persona = { nombre: ‘Juan’ };
const saludarJuan = saludar.bind(persona, ‘Hola’);

saludarJuan(); // “Hola, mi nombre es Juan”
~~~

Resumen:
- call(): Llama a una función inmediatamente con un valor de this específico y argumentos individuales.
- apply(): Llama a una función inmediatamente con un valor de this específico y argumentos como un array.
- bind(): Crea una nueva función con un valor de this específico y argumentos predefinidos que se puede ejecutar más tarde.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

¿Cómo manejarías un array de promesas para que todas se resuelvan secuecialmente en lugar de en paralelo?

A

Para manejar un array de promesas y asegurarte de que se resuelvan secundariamente, puedes usar una estructura de control como un bucle for junto con async/await para esperar la resolución de cada promesa antes de continuar con la siguiente.

Forma de hacerlo secuencialmente:

Usando async/await con un bucle for:

```javascript
async function resolverSecuencialmente(promesas) {
for (let i = 0; i < promesas.length; i++) {
// Espera a que la promesa se resuelva antes de continuar con la siguiente
await promesas[i];
console.log(Promesa ${i + 1} resuelta);
}
}

const promesas = [
new Promise(resolve => setTimeout(() => resolve(‘Primera promesa’), 1000)),
new Promise(resolve => setTimeout(() => resolve(‘Segunda promesa’), 1000)),
new Promise(resolve => setTimeout(() => resolve(‘Tercera promesa’), 1000)),
];

resolverSecuencialmente(promesas);
~~~

En este ejemplo, las promesas se ejecutan una por una. La siguiente promesa no se inicia hasta que la anterior se haya resuelto.

Alternativa con reduce() y async/await:

También puedes usar reduce() para encadenar promesas de forma secuencial:

```javascript
async function resolverConReduce(promesas) {
await promesas.reduce(async (acumulador, promesa) => {
await acumulador; // Espera la promesa acumulada
await promesa; // Espera la siguiente promesa
console.log(“Promesa resuelta”);
}, Promise.resolve()); // Inicia con una promesa resuelta vacía
}

resolverConReduce(promesas);
~~~

Resumen:
- Para ejecutar promesas secuencialmente, puedes usar async/await con un bucle for o el método reduce().
- await garantiza que se espere la resolución de una promesa antes de pasar a la siguiente.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

¿Cómo implementarías un singleton en JavaScript?

A

Aquí tienes la tarjeta sobre cómo implementar un singleton en JavaScript:

Pregunta (Front):
¿Cómo implementarías un singleton en JavaScript?

Respuesta (Back):

Patrón Singleton:
El patrón Singleton asegura que una clase o módulo tenga una única instancia en todo el sistema y proporciona un punto de acceso global a esa instancia. Este patrón es útil cuando necesitas control centralizado, como en el manejo de configuraciones o conexiones a bases de datos.

Cómo Implementarlo:

  1. Usando una función autoejecutable (IIFE):
    Podemos utilizar una función autoejecutable (IIFE) para crear un objeto que contenga una única instancia y que la devuelva si ya existe, o cree una nueva si no la tiene.
  2. Usando una clase (ES6):
    En lugar de usar una función, podemos emplear una clase y almacenar la instancia como un campo estático de la clase.

```javascript
class Singleton {
constructor() {
if (Singleton.instancia) {
return Singleton.instancia;
}
this.valor = “Soy un singleton”;
Singleton.instancia = this;
}

obtenerValor() {
return this.valor;
}
}

// Uso del singleton
const instancia1 = new Singleton();
const instancia2 = new Singleton();

console.log(instancia1 === instancia2); // true, ambas son la misma instancia
~~~

Ventajas del patrón Singleton:
- Instancia única: Garantiza que solo haya una instancia de la clase en todo el sistema.
- Acceso global: Ofrece un único punto de acceso a la instancia.
- Control centralizado: Ideal para administrar recursos compartidos, como configuraciones o conexiones.

Resumen:
El patrón Singleton garantiza que una clase tenga solo una única instancia en la aplicación y que esa instancia esté disponible globalmente. Puedes implementarlo utilizando una IIFE o una clase con un campo estático para almacenar la instancia.

17
Q

¿Qué es un Symbol en JavaScript y cuándo lo utilizarías?

A
  • Un Symbol es un tipo de dato primitivo único e inmutable.
  • Se utiliza principalmente como claves de propiedades en objetos para evitar conflictos.
  • Son útiles cuando necesitas identificadores únicos que no sean susceptibles a sobrescritura o acceso accidental.

Cuando necesitas valores que sean constantes, pero que no sean accesibles a través de otras propiedades del objeto o no puedan ser modificados accidentalmente, como claves internas o privadas.
Cuando desarrollas librerías o módulos, los Symbols pueden evitar que los usuarios modifiquen internamente las claves del objeto, ya que son inaccesibles fuera del módulo.

18
Q

¿Qué es el strict mode en JavaScript y cómo se activa?

A

El strict mode (modo estricto) es una forma de ejecutar código en JavaScript con reglas más estrictas y con restricciones adicionales que ayudan a detectar errores en el código de forma temprana y mejorar la seguridad y el rendimiento.

Al usar el strict mode, JavaScript aplica ciertas restricciones y prohibe ciertas prácticas que son potencialmente problemáticas o propensas a errores. Estas restricciones facilitan el desarrollo de código más robusto y limpio.

Características del Strict Mode:
1. No permite declarar variables sin let, const o var:
En modo estricto, no puedes usar variables no declaradas, lo que ayuda a evitar errores de referencia.

javascript
   'use strict';
   a = 10;  // Error: a is not defined
  
  1. No permite eliminar variables o funciones:
    En strict mode, no puedes usar delete en variables o funciones.
    javascript
    'use strict';
    var x = 10;
    delete x;  // Error: Cannot delete variable 'x'
  2. Evita la duplicación de parámetros en funciones:
    En modo estricto, las funciones no pueden tener parámetros duplicados.
    javascript
    'use strict';
    function suma(a, a) {  // Error: Duplicate parameter name not allowed in this context
      return a + a;
    }
  3. this en funciones no estrictas:
    En el modo estricto, si se invoca una función sin un objeto, el valor de this es undefined, en lugar de ser el objeto global (window en navegadores).
    javascript
    'use strict';
    function saludar() {
      console.log(this);  // undefined
    }
    saludar();
  4. Prohibición de uso de palabras reservadas:
    En strict mode, no se puede usar palabras reservadas que podrían ser reservadas en futuras versiones de JavaScript, como let, class, const, etc.

¿Cómo activar el Strict Mode?

  1. Activarlo a nivel de archivo:
    Puedes activar el modo estricto en todo un archivo JavaScript añadiendo "use strict"; al principio del archivo.

```javascript
‘use strict’;
var x = 10;
~~~

  1. Activarlo a nivel de función:
    También puedes activar el modo estricto dentro de una función para que se aplique solo dentro de esa función.

```javascript
function miFuncion() {
‘use strict’;
var x = 20;
}
~~~

Ventajas del Strict Mode:
- Mayor seguridad: Ayuda a evitar errores comunes, como el uso de variables no declaradas.
- Mejora el rendimiento: Algunos motores de JavaScript pueden optimizar el código cuando está en strict mode.
- Detecta errores con mayor facilidad: Al prohibir ciertas prácticas, los errores son más fáciles de detectar.

Resumen:
El strict mode es una forma de ejecutar el código JavaScript con reglas más estrictas para detectar errores y mejorar la seguridad y el rendimiento. Se activa con "use strict"; al principio del archivo o de una función.

19
Q

¿Qué es un WeakMap y un WeakSet?

A
  • WeakMap: Mapa con claves que son objetos, y valores que pueden ser cualquier tipo. Las claves no impiden la recolección de basura.
  • WeakSet: Set que solo contiene objetos, y estos objetos pueden ser recolectados por el garbage collector.
20
Q

¿Cómo funciona el método Object.freeze()?

A

¿Qué hace Object.freeze()?
El método Object.freeze() en JavaScript se utiliza para congelar un objeto, es decir, previene que se puedan agregar, eliminar o modificar las propiedades del objeto. Después de aplicar Object.freeze(), el objeto se convierte en inmutable en cuanto a su estructura, aunque no congela los objetos internos (profundamente).

Características:
1. Propiedades no pueden ser modificadas: No se pueden cambiar los valores de las propiedades.
2. No se pueden agregar o eliminar propiedades: No puedes agregar nuevas propiedades ni eliminar las existentes.
3. El objeto es inmutable en su nivel superficial: No congela las propiedades de objetos internos (si el valor de la propiedad es un objeto).

Ejemplo básico:

```javascript
const persona = {
nombre: ‘Juan’,
edad: 30
};

Object.freeze(persona);

persona.nombre = ‘Carlos’; // No tiene efecto
persona.pais = ‘España’; // No se agrega la propiedad

console.log(persona); // { nombre: ‘Juan’, edad: 30 }
~~~

¿Qué no hace?
- No congela profundamente los objetos dentro del objeto. Si una propiedad es un objeto, sus propiedades internas pueden ser modificadas.

```javascript
const persona = {
nombre: ‘Juan’,
direccion: {
ciudad: ‘Madrid’
}
};

Object.freeze(persona);

persona.direccion.ciudad = ‘Barcelona’; // Esto es posible
console.log(persona.direccion.ciudad); // “Barcelona”
~~~

Si quieres congelar también los objetos internos, necesitas usar un enfoque recursivo.

Resumen:
- Object.freeze() hace que un objeto sea inmutable a nivel superficial.
- No se pueden agregar, eliminar o modificar propiedades.
- No congela las propiedades de los objetos internos (no es una congelación profunda).

21
Q

Q: Diferencia entre tipos primitivos y referenciados en JavaScript

A

A:

  • Primitivos:
    • Tipos: string, number, boolean, null, undefined, symbol, bigint
    • Se copian por valor, son inmutables
    • sting tiene un numero 7 de compleaños, hace una bolea que le pega a un ñu, que se pone un delfin encima y agarra un simbolo y se lo tira a big foot
  • Referenciados:
    • Tipos: object, array, function, etc.
    • Se copian por referencia, son mutables

🧠 let a = 1; let b = a; b = 2;a sigue siendo 1
📦 let x = {n: 'Ana'}; let y = x; y.n = 'Luis';x.n también es 'Luis'

22
Q

Q: ¿Diferencias entre arrow functions y funciones normales en JavaScript?

A

A:

  • Arrow functions (=>):
    • No tienen su propio this, arguments, super ni new.target
    • No se pueden usar como constructor
    • Sintaxis más corta
  • Funciones normales:
    • Tienen su propio this
    • Se pueden usar como constructor (new)
    • Más flexibles en contexto de objetos/clases

🧠 Útil: Arrow mantiene el this del contexto donde se define

23
Q

Q: ¿Qué es un closure en JavaScript?

A

A:

Un closure es una función que recuerda el ámbito (scope) en el que fue creada, incluso después de que ese ámbito haya terminado.

  • Permite acceder a variables externas aunque la función externa ya haya terminado
  • Útil para encapsular estado o crear funciones privadas

🧠 Ejemplo:
```js
function crearContador() {
let count = 0;
return function () {
count++;
return count;
};
}
const contador = crearContador();
contador(); // 1
contador(); // 2

24
Q

Q: ¿Diferencia entre Promise.all y Promise.race en JavaScript?

A

A:

  • Promise.all([…promesas])
    • Espera que todas se resuelvan
    • Falla si una sola falla
    • Devuelve array de resultados
  • Promise.race([…promesas])
    • Se resuelve/rechaza con la primera promesa que lo haga
    • No espera a las demás

🧠 Útil:
- .all: para tareas que deben completarse todas (ej. cargar datos)
- .race: para obtener el resultado más rápido (ej. timeout o fallback)

25
**Q: ¿Cuáles son las reglas del `this` en JavaScript?**
**A:** 1. **Invocación global** - `this` = `window` (en navegador) o `global` (en Node) 2. **Invocación como método** - `this` = objeto que llama la función 3. **Invocación con `new`** - `this` = nuevo objeto creado 4. **Arrow function** - `this` = del contexto **donde se definió**, no se redefine 5. **`bind`, `call`, `apply`** - Forzan el valor de `this` 🧠 Ejemplo: ```js const obj = { name: "Ana", saludar() { console.log(this.name); } }; obj.saludar(); // "Ana"
26
**Q: ¿Qué son Destructuring, Spread y Rest en JavaScript?**
**A:** - **Destructuring** - Permite extraer valores de un array u objeto en variables. - Sintaxis más limpia para acceder a propiedades o elementos. 🧠 Ejemplo: ```js const [a, b] = [1, 2]; const {name} = {name: "Ana", age: 30};
27
Destructuring - spread - rest
- **Destructuring**: Extrae valores de arrays u objetos en variables. 🧠 `const [a, b] = [1, 2];` 🧠 `const { name } = { name: "Ana", age: 30 };` - **Spread (`...`)**: Expande arrays u objetos. 🧠 `[...arr1, 3]` → combina arrays 🧠 `{ ...obj1, b: 2 }` → copia y agrega propiedades - **Rest (`...`)**: Agrupa el resto de elementos o propiedades. 🧠 `const [x, ...rest] = [1, 2, 3];` 🧠 `function suma(...nums) { return nums.reduce(...); }`
28
**Q: ¿Qué es `addEventListener` en JavaScript?**
**A:** - `addEventListener` es un método para agregar manejadores de eventos a un elemento en el DOM. - Permite escuchar eventos como `click`, `mouseover`, `keydown`, entre otros. 🧠 Ejemplo: ```js const btn = document.querySelector('button'); btn.addEventListener('click', () => alert('Button clicked!'));
29
**Q: ¿Qué es el **bubbling** en los eventos de JavaScript?**
**Q: ¿Qué es event bubbling en JavaScript?** **A:** **Bubbling** es cuando un evento se propaga desde el **elemento que lo originó** hacia sus **elementos padres** en el DOM. 🧠 Ejemplo: ```html
30
**Q: ¿Qué es el **capturing** en los eventos de JavaScript?**
**A:** - **Capturing**: El evento comienza en el **elemento raíz** y se propaga hacia el objetivo del evento. - Se activa cuando el tercer parámetro de `addEventListener` es `true`. 🧠 Ejemplo: ```js document.body.addEventListener('click', () => console.log('Captured!'), true);
31
**Principios SOLID**
A single lady tiene el culo open y closed, de adentro sale liskov que queda internado se pone una ropa de la segregacion es substituido por uno de independiente invertido **SOLID** es un acrónimo que representa cinco principios de diseño de software que buscan mejorar la calidad, legibilidad y mantenibilidad del código: 1. **S** - **Single Responsibility Principle (SRP)**: Un módulo o clase debe tener una única responsabilidad, es decir, debe tener una razón para cambiar. 2. **O** - **Open/Closed Principle (OCP)**: Las clases deben estar abiertas para su extensión, pero cerradas para su modificación. Esto permite agregar nuevas funcionalidades sin modificar el código existente. 3. **L** - **Liskov Substitution Principle (LSP)**: Los objetos de una clase derivada deben ser reemplazables por objetos de la clase base sin alterar el comportamiento esperado del programa. 4. **I** - **Interface Segregation Principle (ISP)**: Los clientes no deben verse obligados a depender de interfaces que no usan. Es mejor tener varias interfaces específicas en lugar de una general. 5. **D** - **Dependency Inversion Principle (DIP)**: Las clases de alto nivel no deben depender de clases de bajo nivel. Ambas deben depender de abstracciones (interfaces o clases abstractas), y las abstracciones no deben depender de detalles, sino que los detalles deben depender de las abstracciones. **Ventajas de seguir SOLID**: - Facilita la escalabilidad del software. - Mejora la reutilización del código. - Aumenta la mantenibilidad y la prueba de unidades.
32
**Q: ¿Cuál es la diferencia entre fetch y axios en JavaScript?**
**A:** - `fetch` es una API nativa del navegador, mientras que `axios` es una librería externa que debes instalar. - `fetch` requiere que conviertas manualmente la respuesta a JSON (`res.json()`), mientras que `axios` lo hace automáticamente. - `axios` maneja errores de red y también errores HTTP (como 404 o 500); en cambio, `fetch` solo lanza errores por fallos de red. - `axios` permite usar interceptores para modificar solicitudes o respuestas, `fetch` no. - Para cancelar solicitudes, `fetch` usa `AbortController`, mientras que `axios` ofrece una forma más sencilla con `CancelToken`. - `axios` funciona bien en Node.js sin configuración adicional; `fetch` necesita un polyfill o una librería como `node-fetch`.
33
**Q: ¿Qué es el Event Loop en JavaScript y cómo funciona?**
**A:** El *Event Loop* es el mecanismo que permite a JavaScript manejar operaciones asincrónicas a pesar de ser un lenguaje de un solo hilo (*single-threaded*). 1. JavaScript ejecuta el código línea por línea en la **Call Stack** (pila de llamadas). 2. Cuando encuentra tareas asincrónicas (como `setTimeout`, `fetch`, promesas, etc.), estas se delegan a la **Web API** del navegador. 3. Una vez completadas, las funciones de callback se colocan en la **Task Queue** (o cola de tareas). 4. El Event Loop monitorea la Call Stack: cuando está vacía, toma la primera tarea de la Task Queue y la ejecuta. **Resultado:** Esto permite que el código no se bloquee mientras espera tareas asincrónicas y mantiene la interfaz fluida.
34
**Q: ¿Qué es el Event Loop en JavaScript y cómo funciona?**
**A:** El *Event Loop* es el mecanismo que permite a JavaScript manejar operaciones asincrónicas a pesar de ser un lenguaje de un solo hilo (*single-threaded*). 1. JavaScript ejecuta el código línea por línea en la **Call Stack** (pila de llamadas). 2. Cuando encuentra tareas asincrónicas (como `setTimeout`, `fetch`, promesas, etc.), estas se delegan a la **Web API** del navegador. 3. Una vez completadas, las funciones de callback se colocan en la **Task Queue** (o cola de tareas). 4. El Event Loop monitorea la Call Stack: cuando está vacía, toma la primera tarea de la Task Queue y la ejecuta. **Resultado:** Esto permite que el código no se bloquee mientras espera tareas asincrónicas y mantiene la interfaz fluida.