0

I am learning about the new features in ES6. I have a question about how let is really behaves, let's check the following example:

function aHero() {
  return 'Boy'
}

function aFoil() {
  return 'Rat'
}

function aDeed() {
  return 'Deed'
}

let sagas = [];
let hero = aHero();
let newSaga = function () {
  let foil = aFoil();
  sagas.push(function () {
    let deed = aDeed();
    console.log(hero + deed + foil)
  });
}

newSaga();
sagas[0]();
sagas[0]();
newSaga();

ES5: var scoped variable to entire function so when the code is running in browser, all variables been hoisted, on the other side in ES6 let scoped variable to its block so when run this code saga[0]() will print three words 'BoyDeedRat'

so I'm wondering how closure is really working with let ??

Hazem Hagrass
  • 9,329
  • 10
  • 32
  • 54
  • 2
    It's not really clear what you're asking here - this code will produce the same result whether you use `let` or `var` (or `const` for that matter) in those places. – James Thorpe May 18 '17 at 12:44
  • @JamesThorpe Yes but it's normal to be working with var, I'm wondering why it's working with let? – Hazem Hagrass May 18 '17 at 12:48
  • 2
    @HazemHagrass Why _wouldn't_ it work with `let`? All the variables are scoped to functions - there's no additional blocks going on here. – James Thorpe May 18 '17 at 12:53
  • @JamesThorpe the question is that the call happened outside the scope, this foil function is just pushed to the array but called outside the scoop – Hazem Hagrass May 18 '17 at 12:56
  • @HazemHagrass Yes, that's [how closures work](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work?rq=1) - the function closes over the scope of `newSaga` that it was declared in. But it makes absolutely zero difference whether `foil` was declared with `let` or `var` in that scope. – Bergi May 18 '17 at 13:00
  • You wouldn't notice any difference between var and let because you have no blocks. But if you do `const values = [1,2,3], funcsViaLet = [], funcsViaVar = []; for(let value of values) { funcsViaLet.push(function(){return value})} for(var value of values) { funcsViaVar.push(function(){return value})}` You will notice that `funcsViaLet[0]()` gives 1, while `funcsViaVar[0]()` gives 3. – Yury Tarabanko May 18 '17 at 13:07
  • I believe it's clear, it was a little bit confusing. I believe that closures are totally different thing separated of using let/var. – Hazem Hagrass May 18 '17 at 13:18

2 Answers2

2

I believe that in javaScript, the interpreter is understanding that you are creating a closure if function keyword is used another function and been returned. in most other common languages, after a function returns, all the local variables are no longer accessible because the context is destroyed, however in JavaScript, if a function is declared within another function, then all local variables can remain accessible after returning from the function you called. In simple words, the inner function will run in it's parent scope and can access all parents variables and function. For detailed info check this link.

Hazem Hagrass
  • 9,329
  • 10
  • 32
  • 54
0

In Chrome, Safari and Firefox, let variables are local to the block, even within a loop.

Both

(function(){
    let fns = [];
    for (let i = 0; i < 5; i++) {
        fns.push(() => { console.log(i); });
    }
    for (let i = 0; i < fns.length; i++) {
        fns[i]();
    }
})();

and

(function(){
    let fns = [];
    for (var i = 0; i < 5; i++) {
        let num = i; // closure will refer to separate values per iteration
        fns.push(() => { console.log(num); });
    }
    for (let i = 0; i < fns.length; i++) {
        fns[i]();
    }
})();

print

0
1
2
3
4

whereas using var instead of let in either case would print 4 five times.

macu
  • 379
  • 1
  • 4
  • 10