0

i'm creating functions inside a for-loop with a variable parameter. Unfortunately, as soon as the for-loop runs a second time, it updates the variable and updates all parameters of the previously generated functions. How can I parse a "detached" value in this loop, so it doesn't get overwritten by the next loop?

My current code is this:

var self = this;  

      for (var i = 0; i < wordObjects.length; i++) {
        var wordCurrent = wordObjects[i].word;
        var wordCorrect = wordObjects[i].correct;
        var moreData =  wordObjects[i].moredata;
        var successFunction = wordObjects[i].successFunction;

        //chain all arguments in one array
        variableArray = []
        variableArray = variableArray.concat(wordCorrect);
        variableArray = variableArray.concat(moreData);

        //create function
        var runFunction = function() {self.executeFunctionByName(successFunction, self, variableArray)};
        this.saveFunctions[wordCurrent] = runFunction;
      };

I tried to generate an object with all arrays inside, but then it didn't pass the arrays at all. It looked like this:

var runFunction = function() {self.executeFunctionByName(successFunction, self, variableArray[i])};

I tried to pass variableArray.slice(); but this didn't seem to work either.

1
  • variableArray is global Commented Aug 25, 2017 at 18:01

1 Answer 1

1

you can solve this by using closures or by using the let statement instead of var. Simply replace var by let.

This works because of the different scoping of let. Take a look at the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

Take this example:

for(var i=0;i<5;i++) {
    var j=i;
    setTimeout(function() { console.log(j); }, i*1000);
}

The output is 5x four.

for(var i=0;i<5;i++) {
    let j=i;
    setTimeout(function() { console.log(j); }, i*1000);
}

The output is 0, 1, 2, 3, 4.


To complete the answer: here the solution with a closure. Closures have a factory method and a closure method. The factory method creates a new scope everytime, the closure can use later.

for(var i=0;i<5;i++) {
    setTimeout((function() { var j=i; return function() { console.log(j); }; })(), i*1000);
}

Another way is to store i as the context of the function. This will work also:

for(var i=0;i<5;i++) {
    setTimeout(function() { console.log(this); }.bind(i), i*1000);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much!
test it. If you like it select it as the answer :) If you have any further questions feel free to ask
Everything works fine, but I now have the problem, that UglifyJS throws an error, as let is ES6 and UglifyJS doesn't support that yet. Is there an alternative way to make it work on older browsers too?
@vinni sure. use one of the closure solutions. That will work before ES6.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.