Reputation: 28572
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
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
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