JavaScript - Ámbito de las variables o "Scope"

JavaScript - Ámbito de las variables o "Scope"

El ámbito de variables, en inglés "scope", tanto en JavaScript como en cualquier otro lenguaje de programación, define la zona del programa en la que podemos utilizar la variable.

En js podemos hablar de dos tipos de ámbitos de variables:

  • Ámbito global.
  • Ámbito local.

Comparto este excelente video:

Ámbito o scope global

Se dice que una variable se encuentra en el scope global cuando está declarada fuera de una función o de un bloque. Vamos a poder acceder a este tipo de variables desde cualquier parte de nuestro código, ya sea dentro o fuera de una función.

El objeto window es un ejemplo de scope global.

Por ejemplo:

var comida = "papas";

function cocinar() {
  return `fritar ${comida}`
}

cocinar(); // Output: "fritar papas"

Como vemos la variable papas esta declarada fuera de la función, por lo cual podrá ser accedida desde dentro de la función.

Ámbito o scope local

Ámbito o scope de función (var)

Las variables que definimos dentro de una función son variables locales, es decir se encuentran en el Scope local. Esto significa que este tipo de variables van a vivir únicamente dentro de la función en donde las hayamos declarado y si intentamos accederlas fuera de ella, dichas variables no van a estar definidas.

Esto nos permite decidir si queremos una variable solo para una determinada función.

Por ejemplo:

function cocinar() {
  var comida = "papas";
  return comida
}

let resultado = `fritar ${comida}` // Output: "ReferenceError: comida is not defined"

Ámbito o scope de bloque (let y const)

En ECMAScript 6 con las keywords let y const surge la posibilidad de tener un scope a nivel de bloque, ósea { }.

Por ejemplo

if (true) {
  var caminar = "Caminando..";

  let correr = "Corriendo..";

  const descansar = "Descansando..";
}

console.log(caminar) // Output: "Caminando.." 
console.log(correr) // Output: "ReferenceError: correr is not defined"
console.log(descansar) // Output: "ReferenceError: correr is not defined"

Ambito o scope lexico

El lexical scope significa que en un grupo anidado de funciones, las funciones internas tienen acceso a las variables y otros recursos de su ámbito padre. Esto significa que las funciones hijas están vinculadas léxicamente al contexto de ejecución de sus padres.

function miFuncion () {
  var nombre = "Charles"
  function pariente() {
    // La variable nombre es accesible
    // Pero la variable apellido no
    function hijo(){
      var apellido = "Darwin"
    }
  }
  console.log(`${nombre} ${apellido}`)
}


miFuncion() // Output: Error porque la variable apellido no esta definida en el ambito de "miFuncion"

Para mas info: Ambito o alcance lexico

Scope chain

Para entender el scope chaining veamos un ejemplo: Nuevo proyecto (2).png

En la función hijo se hace una referencia a la variable nombre, JS buscara esa variable dentro del scope donde se hace la referencia, si no lo encuentra buscara la variable en su función padre y así hasta encontrarla. Si tuviésemos dos variables con el mismo nombre en distintos scope, JS utilizaría al mas cercano.