← JavaScript

Scope y hoisting

¿Qué es el ámbito (scope) en JavaScript y qué tipos existen?

Ver respuesta — intenta responderla en voz alta primero

El ámbito es la región del código donde una variable es accesible. Existe el ámbito global, el ámbito de función y el ámbito de bloque. var usa ámbito de función; let y const usan ámbito de bloque.

El ámbito define "desde dónde puedes ver" una variable.

  • Ámbito global: variables declaradas fuera de cualquier función. Son visibles en todas partes.
  • Ámbito de función: variables declaradas dentro de una función. Solo existen dentro de ella.
  • Ámbito de bloque: variables declaradas con let o const dentro de un bloque { } (un if, un for, etc.). Solo existen dentro de ese bloque.

Una función interna puede acceder a las variables de las funciones que la contienen (esto se llama cadena de ámbitos). Pero no al revés: lo que está adentro no es visible desde afuera.

const global = "soy global";

function externa() {
  const deLaFuncion = "solo dentro de externa";
  console.log(global); // OK: puede ver la global

  if (true) {
    let delBloque = "solo dentro del if";
    console.log(deLaFuncion); // OK: ve la variable de la función
  }
  // console.log(delBloque); // Error: fuera de su bloque
}

externa();
// console.log(deLaFuncion); // Error: fuera de su función

// La cadena de ámbitos: la interna ve a la externa
function padre() {
  const mensaje = "hola";
  function hijo() {
    console.log(mensaje); // OK: el hijo ve la variable del padre
  }
  hijo();
}
padre(); // "hola"

Pensar que una variable declarada con var dentro de un if o de un for solo vive en ese bloque. No es así: var ignora los bloques y su ámbito es toda la función. Solo let y const respetan el ámbito de bloque.

"El ámbito es la región donde una variable es accesible. Tenemos ámbito global, de función y de bloque. var tiene ámbito de función, mientras que let y const tienen ámbito de bloque, o sea que solo existen dentro de las llaves donde se declaran. Además, las funciones internas pueden acceder a las variables de las externas gracias a la cadena de ámbitos, pero no al revés."

Reto rápido

¿Qué imprime esto y por qué?

function prueba() {
  if (true) {
    var a = 1;
    let b = 2;
  }
  console.log(a);
  console.log(b);
}
prueba();
Ver respuesta

Imprime 1 y luego lanza un error b is not defined. var a tiene ámbito de función, así que sobrevive fuera del if. let b tiene ámbito de bloque y no existe fuera del if.