Skip to content

Variable Hoisting in Javascript List of Adders

I have learned the basics of variable hoisting in JavaScript, and am now trying to enhance it by doing some exercises. I’ve come across this piece of code:

function makeAdders(lst) {
    var ar = [];
    for(var i = 0; i < lst.length; i ++) {
        var n = lst[i];
        ar[i] = (x) => x + n;
   }
   return ar;
}

var adders = makeAdders([6,3,5]);

adders.forEach((adder) => {
    console.log(adder(100));
})

This code first creates an array of functions from a given list. Each function adds the same passed number (in this case 100) to a particular value of the list and prints the result. The expected output of this is: 106, 103, 105, and you can achieve this if you use “let” instead of “var” in the for loop. The output of the above code though, is 105, 105, 105, and after some research, I have come to the conclusion that it is because variables i and n are being hoisted (since var is hoisted and let is not).

However, I cannot quite wrap my head around what exactly is going on here and how variable hoisting in this code prevents it from achieving the expected result. Could somebody please help me understand what exactly is happening here? Thank you in advance!

Answer

var hoist based on file (if the variable is in global scope) or function (if the variable is inside a function)

let doesn’t hoist and is hijacked(only scoped) to the nearest curly brackets {}

The code has n that is hoisted (not to the for scope inside {...body of for...}) but to the scope of makeAdders function now when the code

var adders = makeAdders([6,3,5]);

is exectued we have an array of adders functions that all have closure to the one shared n variable (closure is when a function can access its lexical scope even though it’s executed in completely another scope) while n is shared between all functions the last n is set to the value of the last element in the input array which happened to be 5 for now that’s why after all functions are created n have 5 and all adders will return 5 + x