Javascript preguntas entrevista Flashcards
Como funciona la propagacion de eventos de javascirpt?
La delegación de eventos se basa en el concepto de propagación de eventos (event bubbling), donde un evento se origina en el elemento donde ocurre la acción (por ejemplo, un clic en un botón) y luego se “burbujea” hacia arriba a través del árbol DOM hasta llegar al documento raíz.
Al colocar un solo listener en un contenedor común de varios elementos, podemos identificar cuál de los elementos hijos fue el objetivo real (el elemento clicado, por ejemplo) utilizando la propiedad event.target.
event.target.nodeName
event.target.textContent
Como funciona el evento this en javascript?
En JavaScript, this es una referencia al contexto en el que se ejecuta una función. Su valor depende de cómo y dónde se llame la función, lo que puede llevar a diferentes resultados en distintos contextos.
1-En el contexto global (fuera de cualquier función o clase), this hace referencia al objeto global, que es window en navegadores.
2-Dentro de un método de un objeto, this se refiere al propio objeto. Es útil para acceder a las propiedades y otros métodos del mismo objeto.
3-Cuando this se usa en una función que no pertenece a un objeto, su valor depende del modo en que se llame a la función:
En modo estricto (‘use strict’), this es undefined.
Sin modo estricto, this será el objeto global (como window en el navegador).
4-En funciones flecha, this se determina en el momento en que se define la función y mantiene el contexto en el que fue creada. Esto significa que no cambia, independientemente de cómo o dónde se llame la función.
const person = {
name: “Ana”,
greet: () => {
console.log(Hola, soy ${this.name}
);
}
};
person.greet(); // Salida: “Hola, soy undefined”
En el ejemplo anterior, this.name es undefined porque las funciones flecha no tienen su propio this. En su lugar, this se hereda del contexto en el que la función fue definida, que en este caso es el contexto global.
5-En el contexto de una clase, this se refiere a la instancia de esa clase.
6-En un event listener, this se refiere al elemento HTML que desencadenó el evento.
En Resumen
En el contexto global: this refiere al objeto global (como window en navegadores).
En métodos de un objeto: this refiere al objeto que contiene el método.
En funciones independientes: depende de cómo se llama y si se usa use strict.
En funciones flecha: this hereda del contexto en el que la función fue creada.
En clases: this refiere a la instancia de la clase.
En event listeners: this refiere al elemento que desencadena el evento.
Explica la difrencia de call, apply y bind
const car1 = { brand: “Toyota”, model: “Corolla” };
const car2 = { brand: “Honda”, model: “Civic” };
function describeCar(year, color) {
console.log(Este es un ${year} ${this.brand} ${this.model} de color ${color}.
);
}
—————————————————-
// Usando call
para invocar describeCar
con car1
// Usando apply
para invocar describeCar
con car2
describeCar.apply(car2, [2021, “azul”]); // Salida: “Este es un 2021 Honda Civic de color azul.”
// Usando bind
para crear una nueva función describeToyota
const describeToyota = describeCar.bind(car1, 2022, “negro”);
describeToyota(); // Salida: “Este es un 2022 Toyota Corolla de color negro.”
——————————————————-
Cada uno de estos métodos permite invocar describeCar en un contexto específico (this apunta a car1 o car2) y pasar los argumentos que necesita la función.
Explica como funciona la herencia de los prototipos
En JavaScript, la herencia de prototipos permite que los objetos hereden propiedades y métodos de otros objetos. Esto se hace a través de la cadena de prototipos, en la que cada objeto tiene una propiedad interna llamada [[Prototype]] que apunta a otro objeto. Si un objeto necesita acceder a una propiedad o método que no tiene, el motor de JavaScript sube en la cadena de prototipos hasta encontrarla o llegar a null.
EJEMPLO:
- Creamos la función constructora Animal y le añadimos un método hablar.
Creamos la función constructora Perro y, dentro de ella, llamamos al constructor Animal usando Animal.call(this, nombre).
Usamos Object.create para asignar el prototipo de Animal al prototipo de Perro, de manera que Perro hereda de Animal.
Finalmente, asignamos Perro.prototype.constructor = Perro para que Perro mantenga una referencia correcta a su propio constructor.*
// Función constructora 'Animal' function Animal(nombre) { this.nombre = nombre; } // Agregar un método al prototipo de Animal Animal.prototype.hablar = function() { console.log(`${this.nombre} hace un sonido`); }; // Función constructora 'Perro' que hereda de 'Animal' function Perro(nombre, raza) { // Llamamos al constructor de 'Animal' con 'call' Animal.call(this, nombre); // Esto configura 'nombre' para 'Perro' this.raza = raza; } // Hacer que Perro herede de Animal Perro.prototype = Object.create(Animal.prototype); Perro.prototype.constructor = Perro; // Agregar métodos específicos de Perro Perro.prototype.ladrar = function() { console.log(`${this.nombre} ladra: ¡Guau!`); }; // Crear instancias const miPerro = new Perro("Firulais", "Labrador"); miPerro.hablar(); // Salida: "Firulais hace un sonido" miPerro.ladrar(); // Salida: "Firulais ladra: ¡Guau!"
Desde ES6, JavaScript introdujo la sintaxis de class, que simplifica y aclara el proceso de herencia. Las clases son azucar sintáctico sobre el modelo de herencia de prototipos
EXPLICACION
* Definimos la clase base Animal con un constructor y un método hablar.
* Creamos la clase Perro que hereda de Animal usando extends.
* En el constructor de Perro, usamos super(nombre) para llamar al constructor de Animal, lo cual inicializa nombre.
* Agregamos el método ladrar en Perro para un comportamiento específico de los perros.
EJEMPLO
// Definir la clase 'Animal' class Animal { constructor(nombre) { this.nombre = nombre; } hablar() { console.log(`${this.nombre} hace un sonido`); } } // Definir la clase 'Perro' que hereda de 'Animal' class Perro extends Animal { constructor(nombre, raza) { super(nombre); // Llamamos al constructor de la clase padre (Animal) this.raza = raza; } ladrar() { console.log(`${this.nombre} ladra: ¡Guau!`); } } // Crear instancias const miPerro = new Perro("Firulais", "Labrador"); miPerro.hablar(); // Salida: "Firulais hace un sonido" miPerro.ladrar(); // Salida: "Firulais ladra: ¡Guau!"
Explique la diferencia cuando una variable es: null, undefined o undeclared. Como chequearia cada uno de estos estados?
UNDECLARED
Una variable no declarada (undeclared) se crea cuando se asigna un valor a un identificador que no ha sido creado previamente usando var, let o const. Las variables no declaradas se crearan de forma global fuera del contexto actual. En el modo escrito, se creara un ReferenceError cuando se intente asignar un valor a una variable no declarada. Las variables no declaradas son una mala páctica, de la misma forma que las variables globales son una mala práctica.
UNDEFINED
Una variable que es undefined es una variable que ha sido declarada, pero no se le ha asignado un valor. Esta variable es de tipo undefined. Si una función no devuelve un valor especifico, se devolvera por defecto undefined.
Para chequear si una variable es undefined, se utiliza el operador de igualdad estricta(===) o el operador typeof que devolvera la cadena ‘undefined’. Es importante recalcar que no se utiliza el operador de igualdad abstracta (==) ya que este devolverá true si el valor es null.
NULL
Una variable que es null tendra asignado explicitamente el valor null a diferencia de undefined que no se ha asignado ningun valor especifico. Para chequear si una variable es null se utiliza el operador de igualdad estricta ( ===). Es importante recalcar, de la misma forma que anteriormente, no se debe utilizar el operador de igualdad (==) que devolverá true si el valor es undefined.
var foo = null;
console.log(foo === null); // true
console.log(typeof foo === ‘object’); // true
console.log(foo == undefined); // true. Wrong, don’t use this to check!
Explicame que es sincronismo y asincronismo en javascript
En JavaScript, sincronismo y asincronismo determinan cómo se gestionan y ejecutan las operaciones en relación con el ciclo de eventos y el motor de ejecución.
Sincronismo en JavaScript implica que cada instrucción se ejecuta secuencialmente en el "call stack," o pila de ejecución. No se pasa a la siguiente instrucción hasta que la anterior haya concluido, lo cual puede ser restrictivo en el caso de tareas de larga duración, ya que estas bloquean el flujo del programa. Asincronismo introduce una forma no bloqueante de ejecutar código. JavaScript, a través del event loop, permite iniciar tareas asíncronas, como consultas HTTP o temporizadores, que no requieren procesamiento inmediato en la pila principal. Estas tareas se ejecutan en segundo plano y se vuelven a la pila principal solo cuando están listas para completarse. Mecanismos como callbacks, promises, y async/await son herramientas clave para manejar la asincronía en JavaScript, permitiendo una gestión óptima de tareas sin bloquear el flujo de ejecución principal.
En resumen, el asincronismo en JavaScript permite aprovechar mejor el tiempo y recursos del procesador al no esperar a que se complete cada operación para avanzar a la siguiente, facilitando un flujo de trabajo más eficiente.
Que es un IIFE ?
Un IIFE (Immediately Invoked Function Expression) en JavaScript es una función que se declara y se ejecuta inmediatamente después de ser definida. Es útil para crear un ámbito de ejecución aislado, evitando que las variables definidas dentro de él contaminen el ámbito global. La sintaxis básica es:
(function() {
// Código aquí dentro
})();
Desglose:
La función se envuelve en paréntesis (function() { ... }) para que JavaScript la reconozca como una function expression, no como una declaración. Inmediatamente después, () invoca la función.
Ejemplo:
(function() {
let mensaje = “Este es un IIFE”;
console.log(mensaje); // Salida: Este es un IIFE
})();
Que es un closure?
Un closure es la combinación de una función agrupada (dentro de otra) con referencias a su estado adyacente (el entorno léxico). En otras palabras, un closure te da acceso al alcance de una función externa desde una función interna. En JavaScript, los closure se crean cada vez que se crea una función, en el momento de la creación de la función.
function init() {
var name = “Mozilla”; // name es una variable local creada por init
function displayName() {
// displayName() es la función interna que forma el closure
console.log(name); // usar la variable declarada en la función padre
}
displayName();
}
init();
EJEMPLO 2
function makeFunc() {
const name = “Mozilla”;
function displayName() {
console.log(name);
}
return displayName;
}
const myFunc = makeFunc();
myFunc();
EXPLICACION
Ejecutar este código tiene exactamente el mismo efecto que el ejemplo anterior de la función init() anterior. Lo que es diferente (e interesante) es que la función interna displayName() se devuelve desde la función externa antes de ejecutarse.
A primera vista, puede parecer poco intuitivo que este código siga funcionando. En algunos lenguajes de programación, las variables locales dentro de una función existen solo durante la ejecución de esa función. Una vez que makeFunc() termine de ejecutarse, es de esperar que la variable name ya no sea accesible. Sin embargo, debido a que el código sigue funcionando como se esperaba, este obviamente no es el caso en JavaScript.
La razón es que las funciones en JavaScript forman closures. Un closure es la combinación de una función y el entorno léxico dentro del cual se declaró esa función. Este entorno consiste en cualquier variable local que estuviera dentro del alcance en el momento en que se creó el closure. En este caso, myFunc es una referencia a la instancia de la función displayName que se crea cuando se ejecuta makeFunc. La instancia de displayName mantiene una referencia a su entorno léxico, dentro del cual existe la variable name. Por esta razón, cuando se invoca myFunc, la variable name permanece disponible para su uso, y ‘Mozilla’ se pasa a console.log.
Diferencia de foreach y map?
- forEachPropósito: Ejecuta una función específica una vez por cada elemento en el array, pero no devuelve un nuevo array. Solo realiza operaciones para cada elemento.
Retorno: forEach siempre devuelve undefined.
Uso ideal: Cuando quieres hacer una operación sin modificar ni transformar el array, por ejemplo, imprimir valores o actualizar variables externas.
Ejemplo:
const numeros = [1, 2, 3];
numeros.forEach((numero) => {
console.log(numero * 2); // Salida: 2, 4, 6
});
- mapPropósito: Crea un nuevo array aplicando una función a cada elemento del array original. No modifica el array original, sino que devuelve un array nuevo con los resultados.
Retorno: map devuelve un nuevo array con los resultados de aplicar la función.
Uso ideal: Cuando quieres transformar cada elemento y obtener un array nuevo con esos cambios.
Ejemplo:
const numeros = [1, 2, 3];
const dobles = numeros.map((numero) => numero * 2);
console.log(dobles); // Salida: [2, 4, 6]
Explica que es un callback en javascript
Un callback en JavaScript es una función que se pasa como argumento a otra función y se ejecuta después de que la función que la recibe haya completado su trabajo. Los callbacks son fundamentales para manejar operaciones asíncronas, como temporizadores, eventos de usuario y solicitudes de red.
¿Cómo funciona un Callback?
En JavaScript, puedes pasar funciones como argumentos a otras funciones porque las funciones son “ciudadanos de primera clase”. Esto significa que pueden almacenarse en variables, pasarse como argumentos y devolverse como valores. Un callback permite especificar una tarea que se ejecutará después de que otra función termine.
Ejemplo básico de Callback
Supongamos que tienes una función que simula la carga de datos y otra función que se ejecuta cuando esa carga termina:
function cargarDatos(callback) {
console.log(“Cargando datos…”);
// Simula un retraso de 2 segundos setTimeout(() => { console.log("Datos cargados"); callback(); // Ejecuta el callback después de cargar los datos }, 2000); }
function mostrarDatos() {
console.log(“Mostrando datos en pantalla”);
}
cargarDatos(mostrarDatos);
Explicación
La función cargarDatos simula la carga de datos. cargarDatos recibe callback como argumento (en este caso, la función mostrarDatos). Después de simular la carga (usando setTimeout para esperar 2 segundos), se ejecuta callback(), que muestra los datos en la pantalla.
¿Por qué usar Callbacks?
Los callbacks son esenciales para manejar operaciones asíncronas en JavaScript sin detener el flujo de ejecución del programa. Esto es común en:
Consultas a APIs: cuando necesitas esperar una respuesta sin bloquear el navegador. Eventos de usuario: como clics o entradas de teclado. Temporizadores: como setTimeout o setInterval.
Explicame una situacion en la que se utilize una funcion anonima
Una función anónima en JavaScript es una función que se define sin nombre. Este tipo de funciones es útil en situaciones donde solo se necesita ejecutar una acción en un momento específico, sin la necesidad de reutilizar el código en otras partes.
Ejemplo de uso común: Eventos
Una situación donde se usa frecuentemente una función anónima es en la gestión de eventos. Supongamos que deseas ejecutar una acción cuando un usuario hace clic en un botón, pero no necesitas darle un nombre a la función, ya que probablemente solo se utilizará en ese contexto.
const boton = document.getElementById(“miBoton”);
boton.addEventListener(“click”, function() {
console.log(“El botón fue clickeado”);
});
Aquí, la función que se ejecuta cuando se hace clic en el botón es anónima. Esto es conveniente porque:
No se reutiliza: No planeas usar esta función en otro lugar, por lo que darle un nombre no es necesario. Código más limpio y directo: Puedes ver la lógica que se ejecuta en el mismo lugar donde defines el evento.
Otros ejemplos de situaciones donde usar funciones anónimas
setTimeout y setInterval: Si necesitas ejecutar una función después de cierto tiempo o repetidamente, puedes usar una función anónima.
setTimeout(function() {
console.log(“Esto se ejecuta después de 2 segundos”);
}, 2000);
Funciones map, forEach, filter: Al procesar arrays, puedes pasar una función anónima para realizar operaciones en cada elemento.
const numeros = [1, 2, 3]; const dobles = numeros.map(function(numero) { return numero * 2; }); console.log(dobles); // Salida: [2, 4, 6]
En estos casos, una función anónima ayuda a mantener el código organizado y reduce la necesidad de nombres innecesarios.J
How do you organize your code? (module pattern, classical inheritance?)
En el pasado, he utilizado Backbone para mis modelos, lo cual fomenta un enfoque más orientado a objetos (OOP), creando modelos de Backbone y adjuntándoles métodos.
El patrón de módulos sigue siendo excelente, pero hoy en día uso React/Redux, que utiliza un flujo de datos unidireccional basado en la arquitectura Flux. Representaría los modelos de mi aplicación usando objetos simples y escribiría funciones puras de utilidad para manipular estos objetos. El estado se manipula mediante acciones y reducers, como en cualquier otra aplicación de Redux.
Explicación:
Uso de Backbone en el pasado: Con Backbone, se seguía un enfoque de programación orientada a objetos (OOP). En esta metodología, los modelos de datos (las "entidades" de la aplicación) se representaban con instancias de clases de Backbone, y se les añadían métodos para manejar sus propios datos y comportamientos. Cambio hacia React/Redux: Con React y Redux, la forma de manejar datos es diferente. En lugar de usar clases para crear modelos, ahora se opta por representar los datos de la aplicación como objetos simples de JavaScript. Esto se debe a que Redux utiliza el patrón Flux, donde el flujo de datos es unidireccional (es decir, la información fluye en una sola dirección). Manipulación del estado: En Redux, el estado de la aplicación no se modifica directamente. En su lugar: Se crean acciones (actions) para definir qué tipo de cambio debe ocurrir en el estado. Los reducers son funciones puras que toman el estado actual y una acción, y devuelven un nuevo estado basado en esa acción. Uso de funciones puras: Para manipular los datos, en lugar de métodos en los modelos (como en Backbone), se emplean funciones puras de utilidad. Estas funciones reciben los datos como parámetros, los transforman y devuelven los datos modificados sin alterar los originales, lo que ayuda a mantener la inmutabilidad del estado en Redux.
What’s the difference between host objects and native objects?
Native objects are objects that are part of the JavaScript language defined by the ECMAScript specification, such as String, Math, RegExp, Object, Function, etc.
Host objects are provided by the runtime environment (browser or Node), such as window, XMLHTTPRequest, etc
Difference between: function Person(){}, var person = Person(), and var person = new Person()?
This question is pretty vague. My best guess at its intention is that it is asking about constructors in JavaScript. Technically speaking, function Person(){} is just a normal function declaration. The convention is to use PascalCase for functions that are intended to be used as constructors.
var person = Person() invokes the Person as a function, and not as a constructor. Invoking as such is a common mistake if the function is intended to be used as a constructor. Typically, the constructor does not return anything, hence invoking the constructor like a normal function will return undefined and that gets assigned to the variable intended as the instance.
var person = new Person() creates an instance of the Person object using the new operator, which inherits from Person.prototype. An alternative would be to use Object.create, such as: Object.create(Person.prototype).
function Person(name) {
this.name = name;
}
var person = Person(‘John’);
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property ‘name’ of undefined
var person = new Person(‘John’);
console.log(person); // Person { name: “John” }
console.log(person.name); // “john”
Que es y como funciona el operador new?
El operador new en JavaScript se utiliza para crear una nueva instancia de un objeto a partir de una función constructora. Este operador es clave en la programación orientada a objetos (OOP) en JavaScript, ya que permite crear instancias de “clases” (que en JavaScript se definen mediante funciones constructoras) y asociar propiedades y métodos a estos objetos.
¿Cómo funciona el operador new?
Cuando utilizas el operador new para crear una instancia, sucede lo siguiente:
Creación de un nuevo objeto vacío: Se crea un nuevo objeto vacío {}. Enlace del prototipo: El nuevo objeto se asocia con el prototipo de la función constructora, lo que significa que el objeto heredará métodos y propiedades definidas en el prototipo de esa función. Ejecución de la función constructora: La función constructora se ejecuta con el objeto recién creado como su contexto (this). Dentro de esta función, puedes asignar propiedades y métodos al objeto. Retorno del objeto: Si la función constructora no devuelve explícitamente un objeto, el nuevo objeto creado se devuelve por defecto. Si la función constructora devuelve un objeto, ese objeto será el que se devuelva en lugar del objeto creado por new.
Ejemplo básico:
// Función constructora
function Persona(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
}
// Usando el operador new
const juan = new Persona(‘Juan’, 30);
console.log(juan.nombre); // “Juan”
console.log(juan.edad); // 30
What’s the difference between feature detection, feature inference, and using the UA string?
Feature Detection: Verificas directamente si una característica está soportada.
if (‘flex’ in document.body.style) {
// Implementa el diseño de flexbox
} else {
// Usa un diseño alternativo
}
Feature Inference: Asumes que el soporte de una característica implica el soporte de otras.
if (‘querySelector’ in document) {
// Se supone que el navegador soporta otros métodos modernos
}
User-Agent String: Usas la cadena del User-Agent para inferir el navegador o el dispositivo.
const userAgent = navigator.userAgent;
if (userAgent.includes(“Chrome”)) {
// Especifica opciones para Chrome
}
Explain Ajax in as much detail as possible.
AJAX (Asynchronous JavaScript and XML)
AJAX (Asynchronous JavaScript and XML) es una técnica en JavaScript que permite a las aplicaciones web hacer peticiones al servidor para obtener datos sin necesidad de recargar toda la página. Se basa en el uso del objeto XMLHttpRequest o de la API fetch moderna para enviar y recibir datos de manera asíncrona.
Cuando se hace una solicitud AJAX, el navegador envía una petición HTTP al servidor, pero el flujo de la aplicación web no se detiene. Esto es posible gracias a que AJAX es asíncrono, lo cual significa que el código sigue ejecutándose mientras se espera la respuesta del servidor. Cuando el servidor responde, la aplicación recibe esos datos y los usa para actualizar solo ciertas partes de la página, ofreciendo una experiencia más fluida y rápida al usuario.
fetch(‘https://api.example.com/data’)
.then(response => response.json()) // Procesa la respuesta en formato JSON
.then(data => {
console.log(data); // Utiliza los datos recibidos sin recargar la página
})
.catch(error => console.error(‘Error:’, error));
En resumen, AJAX permite que las aplicaciones web interactúen con el servidor para actualizar la información en la página de manera dinámica, sin necesidad de una recarga completa.
What are the advantages and disadvantages of using Ajax?
ventajas y desventajas de AJAX de manera técnica:
Ventajas:
Mayor rapidez y rendimiento: AJAX permite actualizar solo las partes necesarias de una página, en lugar de recargar toda la página web. Esto reduce el tiempo de carga y ahorra ancho de banda, resultando en una experiencia de usuario más fluida y eficiente. Experiencia de usuario mejorada: Gracias a su naturaleza asíncrona, AJAX permite a los usuarios interactuar con otras partes de la página mientras esperan que el servidor responda. Esto significa menos interrupciones y una navegación más dinámica. Interacción en tiempo real: AJAX es ideal para aplicaciones en las que se necesita interactuar en tiempo real, como en chats, notificaciones en redes sociales o recomendaciones de búsqueda en tiempo real.
Desventajas:
Problemas de accesibilidad y SEO: Debido a que AJAX carga contenido de forma dinámica, es posible que algunos motores de búsqueda y tecnologías de asistencia (como lectores de pantalla) no detecten el contenido correctamente, lo cual afecta el SEO y la accesibilidad. Dependencia de JavaScript y conexión a internet: Si el usuario tiene JavaScript deshabilitado o una mala conexión a internet, las funcionalidades basadas en AJAX pueden fallar o no ejecutarse correctamente. Historial de navegación limitado: Como AJAX no recarga la página, los cambios dinámicos no se guardan en el historial de navegación. Esto puede dificultar la navegación "atrás" del usuario, lo que puede ser confuso o frustrante si el usuario pierde el contexto de dónde estaba en la aplicación.
En resumen, AJAX mejora la experiencia de usuario y la eficiencia de carga, pero puede tener limitaciones en accesibilidad, SEO y manejo del historial.
Explain how JSONP works (and how it’s not really Ajax)
Explicación
JSONP (JSON with Padding) es una técnica que permite hacer solicitudes de datos entre distintos dominios. AJAX, por diseño, tiene restricciones de seguridad conocidas como “same-origin policy”, que solo permiten que las solicitudes se hagan al mismo dominio de la página web. JSONP se desarrolló como una solución alternativa para superar estas limitaciones en los navegadores.
A diferencia de AJAX, que utiliza XMLHttpRequest o fetch, JSONP funciona a través de etiquetas
que permiten cargar contenido de otros dominios, ya que los navegadores no bloquean el acceso a archivos JavaScript externos. El servidor envía los datos dentro de una función de JavaScript, que se "llama" automáticamente cuando el archivo se carga en el navegador.
Ejemplo de funcionamiento de JSONP
Imagina que quieres obtener datos de un servidor en otro dominio (por ejemplo, https://api.ejemplo.com/data). En lugar de hacer una solicitud AJAX normal, el navegador crea una etiqueta
que apunta a esa URL. La respuesta del servidor no es un simple JSON; en su lugar, el servidor envía una función con el JSON dentro, algo como esto:
callback({ “nombre”: “Juan”, “edad”: 30 });
Y en el código del cliente, defines callback para que se ejecute cuando la respuesta llegue. Al recibir la respuesta, esta función se ejecuta, y los datos pueden ser procesados sin errores de restricción de dominio.
Diferencias clave entre JSONP y AJAX
Transporte: AJAX usa XMLHttpRequest o fetch, mientras que JSONP usa etiquetas <script>. Seguridad: AJAX tiene restricciones de "same-origin policy", mientras que JSONP evita esta limitación pero abre una puerta a posibles riesgos de seguridad, ya que ejecuta directamente el código de otro dominio. No es realmente AJAX: JSONP no es asíncrono en el sentido de AJAX; utiliza una técnica alternativa para obtener datos, sin hacer una llamada XMLHttpRequest.
Resumen
JSONP permite cargar datos de otros dominios en un navegador de manera segura en su época, aunque actualmente los desarrolladores prefieren soluciones más modernas y seguras, como CORS (Cross-Origin Resource Sharing), en lugar de JSONP.
Que son plantillas en javascript?
JavaScript templating es una técnica que permite crear plantillas de HTML dinámicas y reutilizables usando JavaScript. En lugar de escribir el HTML completo con todos sus datos, se usan “plantillas” que contienen un diseño base y “placeholders” o variables que se reemplazan con datos dinámicos cuando la página se renderiza. Esto es muy útil en aplicaciones web, donde se quiere mostrar datos que cambian constantemente, como en listas de productos, comentarios de usuarios o noticias.
Explicación sencilla
Imagina que tienes una tarjeta para mostrar información de productos. En vez de escribir el HTML completo para cada producto, usas una plantilla que tiene un diseño básico. Luego, llenas esa plantilla con los datos de cada producto específico, como el nombre y el precio. JavaScript toma la plantilla, la copia y reemplaza los espacios en blanco con los datos correctos.
Ejemplo de cómo funciona JavaScript templating
Supongamos que quieres crear una lista de productos con nombre y precio. Puedes usar una plantilla que tenga el formato básico de cada producto y luego, usando JavaScript, reemplazar las partes necesarias.
Ejemplo de plantilla usando “template literals”:
// Datos de ejemplo
const productos = [
{ nombre: “Camiseta”, precio: “$20” },
{ nombre: “Pantalón”, precio: “$40” },
];
// Plantilla en JavaScript
function crearPlantilla(producto) {
return `
<div class="producto">
<h2>${producto.nombre}</h2>
<p>Precio: ${producto.precio}</p>
</div>
`;
}
// Genera el HTML final
let html = ‘’;
productos.forEach(producto => {
html += crearPlantilla(producto);
});
// Inserta el HTML en el DOM
document.getElementById(“contenedor-productos”).innerHTML = html;
En este ejemplo, crearPlantilla es una función que toma un objeto de producto y devuelve un bloque de HTML con los datos de ese producto. Luego, se genera el HTML para todos los productos y se inserta en la página.
Ventajas de usar JavaScript templating
Reutilización de código: Se puede usar la misma plantilla para distintos datos sin escribir HTML varias veces. Facilidad de mantenimiento: Si quieres cambiar el diseño, solo tienes que actualizar la plantilla, y el cambio se reflejará en todas partes. Separación de lógica y diseño: Facilita mantener el código organizado al separar la lógica de la aplicación de la estructura HTML.
Librerías de JavaScript templating
Además de crear plantillas de manera nativa (como en el ejemplo), existen librerías como Handlebars.js, Mustache.js y frameworks como Vue.js o React que permiten crear plantillas más potentes y con características avanzadas, facilitando la creación de aplicaciones complejas.
Como funciona el hoisting en javascript
Hoisting en JavaScript es un comportamiento del lenguaje donde las declaraciones de variables y funciones se “elevan” al inicio de su contexto de ejecución (como una función o el script global), antes de que el código realmente se ejecute. Esto significa que puedes usar variables y funciones en el código antes de haberlas declarado explícitamente en líneas anteriores, aunque el comportamiento exacto depende de cómo se haya hecho la declaración.
Ejemplo de hoisting en funciones
Cuando declaras una función con la palabra clave function, la función completa se “eleva” o “sube” al inicio del contexto. Esto permite llamarla antes de su declaración.
saludar(); // Esto funciona por hoisting y muestra “¡Hola!”
function saludar() {
console.log(“¡Hola!”);
}
Ejemplo de hoisting en variables
Con las variables, el comportamiento varía según cómo se declaran. JavaScript hace “hoisting” de las declaraciones de variables, pero no de sus asignaciones de valor.
Variables declaradas con var
Si declaras una variable con var, JavaScript eleva solo la declaración (no el valor asignado), inicializándola como undefined al principio del contexto. Esto significa que puedes hacer referencia a la variable antes de su declaración, pero su valor será undefined hasta que se asigne.
console.log(nombre); // Muestra undefined
debido al hoisting
var nombre = “Juan”;
console.log(nombre); // Muestra “Juan”
Variables declaradas con let y const
Las variables declaradas con let y const también se “elevan”, pero se colocan en un “temporal dead zone” (zona muerta temporal). Esto significa que, aunque se hace hoisting de la declaración, no pueden usarse antes de la línea en la que se declaran y lanzarán un error si intentas acceder a ellas.
console.log(apellido); // Error: Cannot access ‘apellido’ before initialization
let apellido = “Pérez”;
console.log(apellido); // Muestra “Pérez”
Resumen
Funciones: La declaración completa se eleva al inicio del contexto, por lo que puedes llamarlas antes de declararlas. Variables con var: Solo la declaración se eleva; se inicializan como undefined, y la asignación se hace en su lugar original. Variables con let y const: La declaración se eleva, pero no pueden usarse antes de su línea de declaración, lanzando un error si se intenta.
Hoisting ayuda a entender cómo JavaScript organiza el código internamente y cómo se deben declarar y utilizar variables y funciones para evitar errores o comportamientos inesperados.
Que es el event bubbling
¿Qué es “event bubbling”?
Event bubbling (o propagación de eventos en “burbujeo”) es un mecanismo en JavaScript que se usa para controlar cómo los eventos se transmiten a través de los elementos del DOM. Cuando ocurre un evento (como un clic) en un elemento dentro de otro elemento, el evento se mueve o “burbujea” desde el elemento donde ocurrió inicialmente hacia sus elementos padres. Esto significa que el evento va subiendo en la jerarquía del DOM desde el elemento más específico hasta el más general, llegando hasta el document.
Ejemplo sencillo
Imagina que tienes un botón (<button>) dentro de un div dentro de otro div. Si haces clic en el botón, el evento click primero se activará en el botón, luego en el div que lo contiene, luego en el siguiente div más externo, y así sucesivamente, hasta llegar al document.</button>
<div>
<div>
<button>¡Haz clic aquí!</button>
</div>
</div>
Código de ejemplo con event bubbling
Si añadimos escuchadores de eventos (event listeners) en cada elemento, puedes observar el comportamiento de burbujeo:
document.getElementById(“boton”).addEventListener(“click”, () => {
console.log(“Botón fue clickeado”);
});
document.getElementById(“contenedor-interno”).addEventListener(“click”, () => {
console.log(“Contenedor interno fue clickeado”);
});
document.getElementById(“contenedor-externo”).addEventListener(“click”, () => {
console.log(“Contenedor externo fue clickeado”);
});
Al hacer clic en el botón, la consola mostrará:
"Botón fue clickeado" "Contenedor interno fue clickeado" "Contenedor externo fue clickeado"
Esto muestra cómo el evento de clic “burbujea” hacia arriba.
¿Por qué es útil event bubbling?
Event bubbling permite capturar eventos en un elemento padre en lugar de cada uno de sus elementos hijos. Esto puede hacer que el código sea más eficiente, ya que puedes manejar eventos para varios elementos desde un solo lugar. Por ejemplo, en vez de añadir un evento de clic a cada botón dentro de un div, puedes añadirlo al div mismo y usar la información del evento para ver qué botón fue clickeado.
Cómo detener el bubbling
Si quieres evitar que un evento siga propagándose hacia los elementos padres, puedes usar event.stopPropagation():
document.getElementById(“boton”).addEventListener(“click”, (event) => {
console.log(“Botón fue clickeado”);
event.stopPropagation(); // Detiene la propagación
});
Esto evita que el evento suba a los contenedores, y solo se ejecutará el código asociado al botón.
Resumen
Event bubbling es la propagación de eventos hacia arriba en la jerarquía del DOM. Es útil para manejar eventos de manera eficiente, pero se puede detener con event.stopPropagation() si no quieres que el evento suba por los elementos padres.
ChatGPT puede cometer errores. Comprueba la informació