Preguntas y Respuestas de JS

馃棑 Publicado el 6 de agosto de 2019


馃嚩 & 馃嚘's sobre temas y conceptos de JavaScript a manera de preparaci贸n para entrevistas laborales

Pic for Preguntas y Respuestas de JS

0.1. 驴Qu茅 es hoisting?

En JavaScript cada declaraci贸n de funci贸n o variable es llevada hasta arriba de su scope actual, lo cual es llamado hoisting.

0.2 驴Cu谩l es la diferencia entre var, let y const?

La principal diferencia radica en el scope de cada una de ellas. El t茅rmino scope hace referencia a su alcance de uso (o su disponibilidad para usarse).

var tiene:

  • Scope global (cuando se declara fuera de una funci贸n): esto implica que cualquier variable declarada con var fuera de una funci贸n est谩 disponible para usarse en toda el objeto window o el script donde reside.
  • Scope de funci贸n o local (cuando se declara dentro de una funci贸n): esto implica que 煤nicamente est谩 disponible para su uso dentro de la funci贸n que la declar贸.
  • Adicionalmente, las variables declaradas con var pueden ser redeclaradas y su valor puede actualizarse
  • El hoisting de var sucede hasta arriba de su scope y son inicializadas con el valor undefined

let tiene:

  • Scope de bloque (de c贸digo): el cual es definido por estar dentro de los caracteres { y } lo que implica que las variables declaradas con let 煤nicamente est谩n disponibles dentro del bloque de c贸digo en el que se declararon.
  • Adicionalmente, las variables declaradas con let pueden actualizar su valor, pero no pueden ser redeclaradas (aunque dos variables declaradas con let pueden llamarse igual siempre y cuando no est茅n en el mismo bloque de c贸digo, ergo no ser谩n la misma variable).
  • El hoisting de let sucede hasta arriba de su scope pero NO son inicializadas

const tiene:

  • Scope de bloque
  • Las variables declaradas con const deben ser inicializadas al momento de su declaraci贸n, y no pueden actualizar su valor, ni redeclararse
  • Este comportamiento es diferente cuando se trata de objetos declarados con const, dado que el objeto como tal no podr谩 actualizar su valor, pero sus propiedades SI podr谩n

1. 驴Cu谩l es la diferencia entre undefined y not defined?

Si se intenta usar una variable que no existe y no ha sido declarada, JavaScript arrojar谩 el error var name is not defined y el script detendr谩 su ejecuci贸n. Pero si se utiliza 麓typeof variable_no_declarada麓 茅ste retornar谩 undefined.

Antes de abundar en el tema, hay que entender la diferencia entre declaraci贸n y definici贸n.

Podemos decir que var x es una declaraci贸n porque todav铆a no se ha definido el valor que almacenar谩 x. Pero su existencia ya se declar贸, as铆 como la necesidad de asignar memoria.

var x;            //declarando x
console.log(x)    //undefined

Aqu铆 var x = 1 es ambas: declaraci贸n y definici贸n (tambi茅n se le puede llamar inicializaci贸n). En el ejemplo anterior, la declaraci贸n y asignaci贸n del valor suceden en la misma l铆nea.

La asignaci贸n sucede en orden, de manera que cuando intentamos acceder a una variable que ha sido declarada, pero no ha sido definida, obtenemos el resultado undefined.

var x;    //declaraci贸n
console.log(typeof x === undefined)   //true

Si una variable no ha sido ni declarada ni definida, cuando intentemos hacer referencia a dicha variable, obtendremos not defined.

console.log(y)    //ReferenceError: y is not defined

2. 驴Cu谩l es el resultado del siguiente c贸digo?

var y = 1

if (function f(){}) {
  y += typeof f
}

console.log(y)

El resultado ser谩 1undefined.

El condicional if es evaluado utilizando eval, por lo que eval (function f(){}) retorna el valor function f(){} el cual es true, por lo que dentro del bloque del if, typeof f retorna undefinedporque el bloque del if ejecuta su c贸digo en tiempo de ejecuci贸n, y la condici贸n del if es evaluada tambi茅n durante tiempo de ejecuci贸n.

var k = 1

if (1) {
  eval(function foo(){})
  k += typeof foo
}

console.log(k)

El c贸digo anterior tambi茅n imprimir谩 1undefined.

var k = 1

if (1) {
  function foo(){}
  k += typeof foo
}

console.log(k)

El c贸digo anterior imprimir谩 1function.

驴Cu谩l es la desventaja de crear m茅todos privados en JavaScript?

Una de las desventajas de crear m茅todos privados en JavaScript es que son ineficientes en cuanto al uso de memoria, puesto que cada nueva instancia de la clase tendr谩 su copia 煤nica de dicho m茅todo.

var Empleado = function (nombre, compania, salario) {
  this.nombre = nombre || ''
  this.compania = compania || ''
  this.salario = salario || 5000

  // Metodo privado
  var incrementarSalario = function () {
    this.salario += 1000
  }

  // Metodo publico
  this.mostrarSalarioIncrementado = function () {
    incrementarSalario()
    console.log(this.salario)
  }
}

var emp1 = new Empleado('John', 'HBO', 3000)
var emp2 = new Empleado('Daenerys', 'HBO', 2000)
var emp3 = new Empleado('Bran', 'HBO', 5500)

Cada variable de instancia emp1, emp2 y emp3 tendr谩 su propia copia del m茅todo privado incrementarSalario.

4. 驴Qu茅 es una "closure"?

Una closure (o cerradura) es una funci贸n definida dentro de otra funci贸n (llamada funci贸n padre), y tiene acceso a las variables que han sido declaradas y definidas en el scope de su funci贸n padre.

La closure tiene acceso a las variables en tres diferentes scopes:

  • Variables declaradas en su propia scope
  • Variables declaradas en la scope de su funci贸n padre
  • Variables declaradas en el espacio de nombres global
let globalVar = 'abc';

// Funcion padre auto invocada
(function outerFunction (outerArg) { //Inicio del scope padre
  let outerFuncVar = 'x'; //Variable declarada dentro del scope de outerFunc

// Funcion closure auto invocada
  (function innerFunction (innerArg) {
    let innerFuncVar = 'z';

    console.log(`
      outerArg = ${outerArg}
      outerFuncVar = ${outerFuncVar}
      innerArg = ${innerArg}
      innerFuncVar = ${innerFuncVar}
      globalVar = ${globalVar}`)
  })('y')
})('w')

innerFunction es una closure definida dentro de outerFunction por lo que tiene acceso a todas las variables declaradas y definidas dentro del scope de outerFunction, as铆 como a todas las variables definidas en el espacio de nombres global.

La salida del c贸digo anterior ser谩:

outerArg = w
outerFuncVar = x
innerArg = y
innerFuncVar = z
globalVar = abc

5. Escribir una funci贸n multip que produzca la siguiente salida al invocarse:

console.log(multip(2)(3)(4)) // 24
console.log(multip(4)(5)(6)) // 120

La soluci贸n es la siguiente:

function multip (a) {
  return function (b) {
    return function (c) {
      return a * b * c
    }
  }
}

La funci贸n multip retorna una funci贸n an贸nima, que a su vez retorna otra funci贸n an贸nima que retorna la multiplicaci贸n de los argumentos de cada funci贸n.

Como se mencion贸 anteriormente, una funci贸n definida dentro de otra tendr谩 acceso a las variables de la funci贸n padre, y

  • Una funci贸n es una instancia del tipo Object
  • Una funci贸n puede tener propiedades y tiene un enlace a su m茅todo constructor
  • Una funci贸n puede ser almacenada como una variable
  • Una funci贸n puede ser pasada como par谩metro a otra funci贸n
  • Una funci贸n puede ser retornada por otra funci贸n

6. 驴C贸mo vaciar un arreglo?

Teniendo el arreglo

let arr = ['a', 'b', 'c', 'd', 'e']

Opci贸n 1:

arr = []

Este m茅todo actualiza el valor de la variable arr a un arreglo vac铆o y se recomienda s贸lo si no existen referencias previas a la variable arr dado que si existen referencias previas, 茅stas no se actualizar谩n. Por ejemplo:

let arr = ['a', 'b', 'c', 'd', 'e']
let otroArr = arr
arr = []
console.log(otroArr) // ['a', 'b', 'c', 'd', 'e']

Opci贸n 2:

arr.length = 0

Esta opci贸n actualiza el arreglo estableciendo su longitud a 0. Se recomienda este m茅todo si existen referencias a la variable arr y se desean actualizar todas las referencias. Por ejemplo:

let arr = ['a', 'b', 'c', 'd', 'e']
let otroArr = arr
arr.length = 0
console.log(otroArr) // []

Opci贸n 3:

arr.splice(0, arr.length)

Esta forma de vaciar el arreglo tambi茅n actualizar谩 todas las referencias al mismo

Opci贸n 4:

while (arr.length) {
  arr.pop()
}

Este m茅todo no se recomienda.

7. 驴C贸mo verificar si un objeto es un arreglo?

Podemos verificar si un valor determinado es un arreglo usando el m茅todo Array.isArray() disponible en ES6 o superior

let arr = ['a', 'b', 'c', 'd', 'e']`

La mejor forma de verificar si un objeto es instancia de una clase particular es usando el m茅todo Object.prototype.toString. Tomando como ejemplo

8. 驴Cu谩l es el resultado del siguiente c贸digo?

let salida = (function (x) {
  delete x
  return x
})(0)

console.log(salida)

El resultado ser谩 0 dado que la instrucci贸n delete funciona 煤nicamente para propiedades de objetos y en este caso x es una variable local.

9. 驴Cu谩l es el resultado del siguiente c贸digo?

let x = 1
let salida = (function () {
  delete x
  return x
})()

console.log(salida)

El resultado ser谩 1 porque x no es una propiedad de un objeto, sino una variable global.

10. 驴Cu谩l es el resultado del siguiente c贸digo?

let x = {foo: 'bar'}
let salida = (function () {
  delete x.foo
  return x.foo
})()

console.log(salida)

El resultado ser谩 undefined. En este caso el operador delete eliminar谩 la propiedad foo del objeto x. Posteriormente se intentar谩 referenciar a la propiedad eliminada, por ende el resultado undefined.

11. 驴Cu谩l es el resultado del siguiente c贸digo?

let Empleado = {
  empresa: 'HBO'
}

let emp1 = Object.create(Empleado)
delete emp1.empresa

console.log(emp1.empresa)

El resultado ser谩 HBO. Aqu铆 emp1 tiene a empresa como propiedad de su prototype. El operador delete no elimina propiedades de prototype.

El objeto emp1 no tiene a empresa como propiedad propia (lo podemos verificar con un console.log(emp1.hasOwnProperty('empresa')) // false).

Aunque si podr铆amos eliminar la propiedad empresa directamente del objeto Empleado utilizando delete Employee.company o tambi茅n del objeto emp1 utilizando delete emp1.__proto__.empresa

12. 驴Cu谩l es el resultado del siguiente c贸digo?

let arr = [1, 2, 3, 4, 5, 6, 7]
delete arr[2]

console.log(arr.length)

El resultado ser谩 7 dado que el operador delete elimina el elemento del arreglo, pero no modifica su longitud. Esto es cierto incluso cuando se eliminan todos los elementos del mismo.

En algunos ambientes como Google Chrome o node, si intentamos imprimir en consola el arreglo, nos mostrar谩 algo como [ 1, 2, <1 empty item>, 4, 5, 6, 7 ]

13. 驴Cu谩l es el resultado del siguiente c贸digo?

let bar = true
console.log(bar + 0)
console.log(bar + 'xyz')
console.log(bar + true)
console.log(bar + false)

El resultado ser谩 1, "truexyz", 2, 1 esto por c贸mo se comporta el operador de adici贸n. Como gu铆a general tenemos:

  • Number + Number = Addition
  • Boolean + Number = Addition
  • Boolean + Number = Addition
  • Number + String = Concatenation
  • String + Boolean = Concatenation
  • String + String = Concatenation

14. 驴Cu谩l es el resultado del siguiente c贸digo?

let z = 1, y = z = typeof y
console.log(y)

El resultado ser谩 undefined. Esto es por la regla de asociatividad en la precedencia de operadores (en particular para el operador asignaci贸n, el cual tiene asociatividad de derecha a izquierda).

Lo que sucede en el c贸digo anterior es que primeramente se eval煤a el typeof y, el cual en ese momento es undefined. Posteriormente se asigna a z el valor undefined, y luego dicho valor a y. Finalmente se declara e inicializa z = 1.

15. 驴Cu谩l es el resultado del siguiente c贸digo?

// NFE o Named Function Expression
var oks = function bye () { return 12; };
typeof bye();  

El resultado es un Reference Error. Para que el c贸digo funcione lo podemos reescribir de varias formas:

var oks = function () { return 12; };
typeof bye();  

o como

function oks () { return 12; };
typeof bye();  

Lo cual nos retornar谩 el valor de number.

La definici贸n de una funci贸n s贸lo puede tener una variable de referencia como nombre. En el segundo bloque de c贸digo la variable oks hace referencia a una funci贸n an贸nima, y en el tercer bloque, la definici贸n de la funci贸n es su propio nombre.

16. 驴Cu谩l es la diferencia entre las siguientes declaraciones de funciones?

let oks = function () {
  // codigo
}
function bye () {
  // codigo
}

La principal diferencia es que la funci贸n oks es definida en tiempo de ejecuci贸n mientras que la funci贸n bye es definida en tiempo de an谩lisis. Para entender mejor veamos el siguiente ejemplo:

  • Declaraci贸n de funci贸n en tiempo de ejecuci贸n
<script>
  oks(); //Llamar a la funci贸n oks arrojar谩 un error
  let oks = function () {
    console.log('Hola mundo')
  }
</script>
  • Declaraci贸n de funci贸n en tiempo de an谩lisis
<script>
  bye(); //Llamar a la funci贸n bye no arrojar谩 un error
  function bye () {
    console.log('Hola mundo')
  }
</script>

Una ventaja de la primer forma de declarar funciones es que se pueden declarar con base en cierta condici贸n, no as铆 de la segunda forma.

17. 驴Cu谩l es el resultado del siguiente c贸digo?

var salario = '$10000';

(function () {
  console.log(`El salario original es de ${salario}`)
  var salario = '$15000'
  console.log(`El nuevo salario es de ${salario}`)
})()

El resultado para salario ser铆a primero undefined y luego $15000 esto debido al hoisting para variables declaradas con var (explicado al inicio de esta publicaci贸n).

18. 驴C贸mo calcular la longitud de un arreglo asociativo en JavaScript?

Suponiendo el siguiente arreglo asociativo:

let assoc = {
  A: 1,
  B: 2
}

assoc['C'] = 3

Podemos calcular su longitud utilizando el m茅todo Object.keys() (disponible a partir de ES6) de la siguiente manera:

console.log(Object.keys(assoc).length)

Preguntas te贸ricas

  • 驴Cu谩l es la diferencia entre null, undefined y undeclared y c贸mo revisar dichos valores?
  • undefined es una variable que ha sido declarada pero no tiene asignado un valor, tambi茅n puede ser un tipo de variable typeof variable === undefined
  • null puede ser el valor asignado a una variable para representar ausencia de un valor, tambi茅n es un tipo de objeto typeof null // object
  • undeclared indica que una variable no ha sido declarada, al hacer referencia a ella se arrojar谩 un ReferenceError: variable is not defined
  • 驴Cu谩l es la diferencia entre los operadores == y ===?

La diferencia es que el operador == no compara el tipo de dato de los elementos a comparar y el === si. Por ejemplo:

0 == false // true, auto type coercion
0 === false // false, diferente tipo
1 == "1" // true, auto type coercion
1 === "1" // false, diferente tipo
  • 驴Qu茅 herramientas del lenguaje JavaScript se pueden utilizar para iterar sobre las propiedades de un objeto y los elementos de un arreglo?

Para iterar sobre las propiedades de un objeto podemos utilizar el bucle for...in y para iterar sobre los elementos de un arreglo podemos utilizar el bucle for...of

  • 驴Cu谩l es la diferencia entre el bucle Array.forEach() y el m茅todo Array.map()?

El bucle forEach() ejecuta una funci贸n una vez por cada elemento de un arreglo (mut谩ndolo), pero no entrega un valor de retorno.

El m茅todo map() crea un nuevo arreglo con el resultado de llamar una funci贸n en cada elemento del arreglo a mapear y retorna el nuevo arreglo (del mismo tama帽o que el original).

  • Menciona un uso com煤n de una funci贸n an贸nima

En operaciones as铆ncronas, las callback suelen ser funciones an贸nimas

  • 驴Cu谩l es la diferencia entre native objects y host objects?

Un native object es un objeto definido por alguna especificaci贸n de ECMAScript (Object, Date, Math, parseInt, eval, String.indexOf, String.replace, etc).

Un objeto host es cualquier objeto que no sea un objeto nativo, como WebAPIs (XMLHttpRequest, setTimeout, getElementsByTagName, window, document, location, history, etc.).

  • 驴Cu谩l es la diferencia entre Function.apply y Function.call?

Ambas permiten especificar un valor de this para la funci贸n a invocar, pero la diferencia es que apply te permite invocar a la funci贸n con sus argumentos especificados como un arreglo y call requiere que los argumentos sean listados espec铆ficamente (separados por comas).

  • 驴Cu谩l es la diferencia entre function Person(), var person = Person() y var person = new Person()?

function Person() es una declaraci贸n de una funci贸n.

var person = Person() retorna el valor de la funci贸n Person() y se lo asigna a la variable person

var person = new Person() crea una instancia basada en la funci贸n Person() por lo que person es un objeto.

  • 驴Cu谩l es la diferencia entre function foo(){} y var foo = function(){}?

La primera es una declaraci贸n de funci贸n, la cual es evaluada en la scope que la contiene y la segunda es una expresi贸n funci贸n, la cual crea una funci贸n an贸nima (aunque podr铆a tener un nombre) y la asigna a la variable foo

  • 驴D贸nde se deben poner los scripts de JS en una p谩gina web?

Depende, pero por lo general convienen poner todos los scripts en un solo archivo minificado, puesto que se realizar谩 una sola petici贸n para obtener el archivo vs m煤ltiples. En el caso de JS en l铆nea (in-line) es recomendable ponerlo hasta abajo de la etiqueta body de cierre, de esta manera no bloquear谩 el render de la p谩gina.

  • 驴Qu茅 es un objeto JavaScript?

Es una colecci贸n de datos que contienen propiedades (asociaci贸n entre pares llave-valor) y m茅todos. Cada elemento en un documento es un objeto manipulable gracias al DOM.

  • 驴Qu茅 es event bubbling y event capturing?

Ambos son m茅todos de propagaci贸n de eventos en la API del DOM HTML. El event bubbling ocasiona que todos los eventos en los nodos hijo sean pasados a los nodos padre. En el event capturing el elemento exterior captura el evento y lo propaga hacia los elementos internos.

  • 驴Qu茅 es this en JavaScript y c贸mo ha cambiado el uso de this a partir de ES6?

This es una palabra reservada que hace referencia al objeto due帽o del m茅todo.

Su uso ha cambiado en particular con la implementaci贸n de las arrow functions las cuales no tienen su propio valor de this sino que hacen referencia al valor de this dentro del contexto de ejecuci贸n que la contiene.

  • 驴Qu茅 es una closure?

Una funci贸n declarada dentro de otra funci贸n y que tiene acceso a su propia scope y a la de su funci贸n padre

  • 驴Qu茅 es el global namespace o espacio de nombres global?

Un espacio de nombres es un "contenedor" para un conjunto de identificadores, funciones, m茅tudos, etc. El espacio de nombres global es el "mas exterior", correspondiente al objeto global.

  • Menciona dos paradigmas de programaci贸n importantes en JavaScript
  1. Orientado a Objetos, soportado a trav茅s de la herencia por prototipos
  2. Funcional
  • 驴Qu茅 es programaci贸n funcional?

La programaci贸n funcional produce programas a trav茅s de la composici贸n matem谩tica de funciones y evita compartir su estado, as铆 como mutaci贸n de datos y evitar efectos secundarios (funciones puras).

  • 驴Qu茅 diferencia hay entre herencia de clases y herencia por prototipos?

Herencia por clases: Las instancias (objetos) heredan de clases (como un plano o descripci贸n de la clase) y crean relaciones sub-clase: taxonom铆as de jerarqu铆as de clases. Las instancias normalmente se instancian usando funciones contructor con la palabra reservada new. La herencia por clases puede o no usar la palabra reservada class de ES6.

Herencia por prototipos: Las instancias heredan directamente de otros objetos, normalmente a trav茅s de funciones que implementan el patr贸n de dise帽o factory o usando Object.create(). Las instancias pueden estar compuestas de muchos objetos diferentes, permitiendo "herencia selectiva".

  • 驴C贸mo funciona la herencia por prototipos?

Un objeto puede apuntar a otro y heredar todas sus propiedades. Todos los objetos en JavaScript tienen un enlace al objeto prototipo y cuando se quiere acceder a la propiedad de un objeto, dicha propiedad no s贸lo se buscar谩 en el objeto sino tambi茅n en su prototipo, el prototipo de su prototipo y as铆 sucesivamente hasta que se encuentre o se llegue al fin de la cadena de prototipos.

  • 驴Qu茅 es two way data binding (o enlace de datos bidireccional) y el flujo de datos unidireccional y c贸mo se diferenc铆an?

El two way data binding significa que los campos en la UI est谩n enlazados din帽amicamente a un modelo de datos de tal forma que cuando la UI cambia, el modelo de datos tambi茅n cambia, y viceversa. Por ejemplo el framework Angular

El flujo de datos unidireccional significa que el modelo es la 煤nica fuente de verdad. Los cambios en la UI mandan un mensaje de cambio de datos en el modelo (o store, en React) generado por el usuario. 脷nicamente el modelo tiene acceso a cambiar el estado de la aplicaci贸n. Esto hace que los datos fluyan en una 煤nica direcci贸n. Por ejemplo el framework React.

  • 驴Cu谩les son los pros y contras de arquitecturas monol铆ticas vs arquitecturas orientadas a microservicios?

Una arquitectura monol铆tica significa que la aplicaci贸n est谩 escrita como una unidad de c贸digo con cohesi贸n, cuyos componentes est谩n dise帽ados para trabajar en conjunto, compartiendo el mismo espacio de memoria y recursos.

Pros de arq. monol铆tica: Su mayor ventaja es que la mayor铆a de aplicaciones t铆picamente tienen un gran n煤mero de responsabilidades compartidas, como generaci贸n de bit谩coras (logging), establecer l铆mites de consumo (rate limitting) y funciones de seguridad, como auditor铆as y protecci贸n contra DOS.

Contras de arq. monol铆tica: Los servicios monol铆ticos tienden a estar altamente acoplados y a medida que la aplicaci贸n evoluciona, se vuelve dificil aislar los servicios con objeto de brindarles indenendencia en cuanto a escalabilidad o mantenibilidad. Tambi茅n son mas dif铆ciles de entender porque normalmente tienen muchas dependencias y efectos secundarios que no son tan obvios cuando se observa un servicio o controlador particular.

Pros de arq. microservicios: Normalmente est谩n mejor organizadas puesto que cada microservicio tiene un trabajo espec铆fico y no le deber铆a de afectar el trabajo de los otros componentes. Est谩n bajamente acoplados y son m谩s f谩ciles de componer y reconfigurar para diferentes prop贸sitos. Tambi茅n suelen tener mejor desempe帽o dependiendo de c贸mo est茅n organizados puesto que es posible (y com煤n) que est茅n aislados y se puedan escalar independientemente del resto de la aplicaci贸n.

Contras de arq. microservicios: Mientras se desarrolla una arquitectura de microservicios probablemente se vislumbren temas o asuntos que no estaban considerados originalmente en la etapa de dise帽o. Tambi茅n se crea un esfuerzo adicional para separar los m贸dulos de acuerdo a responsabilidades, o encapsular responsabilidades compartidas en otra capa de servicio por la cual haya que rutear todo el tr谩fico. Normalmente los microservicios se despliegan en su propia VM o contenedor, causando mas trabajo en administrar dicha virtualizaci贸n u orquestaci贸n de cluster contenedores.

  • 驴Qu茅 es la programaci贸n as铆ncrona y porqu茅 es importante en JavaScript?

La programaci贸n s铆ncrona significa que, exceptuando condicionales y llamadas a funciones, el c贸digo es ejecutado secuencialmente de arriba hacia abajo, generando bloqueos en tareas de larga ejecuci贸n, como peticiones a red o lectura/escrituda a disco.

La programaci贸n as铆ncrona significa que la ejecuci贸n se realiza en un bucle de eventos (event loop). Cuando se realiza una operaci贸n bloqueante (como las mencionadas anteriormente) la petici贸n inicia y el c贸digo sigue ejecut谩ndose sin generar bloqueos. Cuando la respuesta a la petici贸n est谩 lista, se genera una interrupci贸n lo cual ocasiona que se ejecute un manejador de eventos (event handler), donde el flujo de control contin煤a. De esta forma, un 煤nico hilo de un programa puede manejar muchas operaciones concurrentes.

Las UI son as铆ncronas por naturaleza, lo que significa que el servidor trabaja de la misma manera, esperando la respuesta de la red en un bucle y aceptando m谩s peticiones entrantes mientras que se atiende la primera.

Esto es importante en JavaScript porque incrementa el desempe帽o en el servidor y es un comportamiento "natural" en el c贸digo del cliente.