0

Is it possible to push functions to an array using var instead of let. The code I'm looking at is:

function slideRightLoop() {
    let work = [];

    for (var n = 1; n < 5; n++) {
        let next = (n + 1 < 5) ? n + 1 : 1;
        let el = document.querySelector(".position_" + n)[0];
        var change = function change () {
            el.classList.add("position" + next);
            el.classList.remove("position_" + n);
        }
        work.push(change);
    }

    work.forEach(function (n) { 
      return n();
    });
}
axecopfire
  • 512
  • 5
  • 16
  • 1
    why doesn't var work for you? – terary Jun 13 '18 at 20:39
  • @terary I think because its block scoped right now on each iteration let gets reassigned and maintains scope. However when I use var I think it gets hoisted and doesn't reassign on each loop. – axecopfire Jun 13 '18 at 20:43
  • 2
    `because compatibility` What do you mean by compatibility? If you need to support ancient browsers, you can just run it through Babel. Also, instead of using `querySelectorAll` and selecting the first element in the `NodeList`, just use `querySelector` instead. I'm not seeing the point of putting each function in an array and then executing it - why not just have a loop that executes each block? – CertainPerformance Jun 13 '18 at 20:50
  • @CertainPerformance Changed to `querySelector` and got rid of the arrow function and changed some vars in there. I just don't know if it is possible to keep this type of silliness with the function pushes to an array that could use `var` or if it just needs to be scrapped and just push elements a regular array on execution. – axecopfire Jun 13 '18 at 20:57

2 Answers2

1

You can just put it into https://babeljs.io/repl/ and see what is converted to. The simplest way is to make the loop body a function which accepts all loop variables as arguments:

function slideRightLoop(n, work) {
  var next = (n + 1 < 5) ? n + 1 : 1;
  var el = document.querySelector(`.position_${n}`);
  var change = function change () {
      el.classList.add(`position_${next}`);
      el.classList.remove(`position_${n}`);
  }
  work.push(change);
}

function slideRight() {
    var work = [];

    for (var n = 1; n < 5; n++) {
      slideRightLoop(n, work);
    }

    work.forEach(function (n) { 
      return n();
    });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

To do what you want with var, you could use a temporary function to create a closure around your n and next values.

I changed the code a little bit to leave the meaningful part

function slideRight() {
    let work = [];

    for (var n = 1; n < 5; n++) {
        var next = (n + 1 < 5) ? n + 1 : 1;
        let change = function(next, n){
          return function change () {
          console.log(next, n)
        }}
        work.push(change(next, n));
    }
  

    work.forEach(function (n) { 
      return n();
    });
}

slideRight()

This should output the desired values

Francesco
  • 4,052
  • 2
  • 21
  • 29