Scope y closures en JavaScript

Scope

Define el alcance de una variable, dónde puede o no usarse.

function countToN(n) {
  var i = 1;
  while(i < n + 1) {
    console.log(i);
    i++;
  }
}

console.log(i);

Si definimos una variable utilizando var, el scope de la misma va a ser la función donde fue declarada.

Esta variable será local dentro de esta función.

function countToN(n) {
  var i = 1;
  while(i < n + 1) {
    console.log(i);
    i++;
  }
}

var j = 1;

En este caso, la variable j está definida fuera de cualquier función, por lo que su scope pasa a ser el global.

Es decir, puedo acceder a j y utilizarla desde cualquier parte del código de mi programa.

¿Esto es bueno o malo? ¿Por qué?

var i = 7;

if (i > 0) {
    var daysOfTheWeek = 
        ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 
         'Friday', 'Saturday', 'Sunday'];
}

while (i >= 0) {
    console.log(daysOfTheWeek[i]);
    i--;
}

si usamos var, no tenemos scope por bloque

for(var i = 1; i <= 10; i++) {
    console.log(i);
}

console.log(i);
var deportista = {
    nombre: 'Luciana Aymar',
    deporte: 'Hockey',
    edad: 40,
    decirDeporte: function() {
        console.log(deporte);
    }
}
var deportista = {
    nombre: 'Luciana Aymar',
    deporte: 'Hockey',
    edad: 40,
    decirDeporte: function() {
        console.log(deportista.deporte);
    }
}

si las variables definidas con var no estan dentro de alguna funcion, pertenecen al scope global

let, const

for(let i = 1; i <= 10; i++) {
    console.log(i);
}

console.log(i);

a diferencia de cuando utilizamos var para definir variables, let y const determinan un scope por bloque

Closures

Es una función que tiene un ambiente de variables (scope) ligado, que puede utilizarse incluso por fuera de éste

let a = 2;
let b = 3;

function sumAyB() {
    return a + b;
}

a y b son variables ligadas a la función

Las closures nos permiten pasar funciones por parámetro

let a = 2;
let b = 3;

function sumAyB() {
    return a + b;
}

function showInConsole(aFunction) {
    console.log(aFunction());
}

function substract(a, b) {
    return a - b;
}

Hacer ejemplo con closure, no closure

closure me permite pasar una funcion por parametro => CALLBACKS

function greet(nombre, apellido) {
    const mensaje = 'Hola';

    return function() {
        console.log(`${mensaje} ${nombre} ${apellido}!`);
    }
}

const greetMPJ = greet('Mattias Petter', 'Johansson');

La función que se retorna pertenece al mismo scope que mensaje, por lo que puede acceder y utilizarlo

 

https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q/

Utilizando closures, implementar la función

 

sucesor(numero)

 

Debe retornar otra función que al ejecutarse devuelva el sucesor del numero pasado por parámetro.

Por ejemplo:

 

const sucesorDe3 = sucesor(3);

 

y cuando la ejecutamos:

 

sucesorDe3() // Tiene que devolver 4

 

function sucesor(numero) {
  const sucesor = numero + 1;

  return function mostrarSucesor() {
    console.log(sucesor);
  }
}

mostrarSucesor viene con las variables acopladas del contexto donde fue definida. Es decir, tenemos un closure

Por eso es que tiene acceso a la variable sucesor y por más que la ejecutemos en otro lugar, por ejemplo al hacer sucesorDe3() devuelve el resultado correcto

function sucesor(numero) {
  const sucesor = numero + 1;

  return function mostrarSucesor() {
    console.log(sucesor);
  }
}
function counter() {
    let counter = 0;
    const counterButton1 = document.querySelector('#button1');
    const counterButton2 = document.querySelector('#button2');

    const print = function() {
        console.log(counter);
    }

    counterButton1.addEventListener('click', function count1() {
        counter++;
        print();
    })

    counterButton2.addEventListener('click', function count2() {
        counter++;
        print();
    })
}

+Info

Scope y closures en JavaScript

By Nicolás Quiroz

Scope y closures en JavaScript

  • 185