Just a learner
Just a learner

Reputation: 28572

Javascript create a list of functions dynamically

I have a piece of JavaScript code that I want to create a list of functions. All the functions will be put in a dictionary d. d["a"] will give me the function function() {console.log("a")} and d["b"] will give me the function function() {console.log("b")} etc. This is my code:

var a = "abcdefghijklmnopqrstuvwxyz1234567890".split("");
var d = {};
for(var l = a.length, i = 0; i < l; i++)
{
    d[a[i]] = function(){console.log(a[i])};
}

However, when I run the above code, d["a"] and d["b"] will be the same, they all point to function(){console.log(a[i])}. How to get what I want?

Thanks.

Upvotes: 3

Views: 457

Answers (2)

Nick Husher
Nick Husher

Reputation: 1884

They don't point to the same instance of function(){console.log(a[i])}, instead, you've created a bunch of functions that all use the same reference to i. The value that i points at changes as the for loop executes.

The other answers provided will work, but it involves generating twice as many functions as you need.

function makeLogFunction(whatToLog) {
    return function() {
        console.log(whatToLog);
    }
}

var a = "abcdefghijklmnopqrstuvwxyz1234567890";
var d = {};
for(var l = a.length, i = 0; i < l; i++) {
    d[a[i]] = makeLogFunction(a[i]);
}

Here, I have a makeLogFunction that will return a new function that always prints whatToLog. The other answers will generate a new "version" of the makeLogFunction every time the loop executes. For very large sets of data, this is a waste of time and memory.

This approach has added advantages of clarity and reusability. If there's a significant amount of logic happening in your loop, encapsulating it in a named function allows future reviewers to get a sense of what's going on by the name you give to the function. You can also reuse the function in other parts of your application.

Upvotes: 0

user229044
user229044

Reputation: 239270

You need to give each instance of the function its own variable:

for(var l = a.length, i = 0; i < l; i++)
{
  (function (x) {
    d[a[x]] = function(){console.log(a[x])};
  })(i)
}

Upvotes: 2

Related Questions