0

Why does each iteration of this:

var o = {};

var foo = [['a',1],['b',2],['c',3],['d',4],['e',5]];

for(var i = 0; i < 5; i++)
{
  o.__defineGetter__(foo[i][0], function() {
    return foo[i][1]; 
  });
  console.info(JSON.stringify(o));
}

Reset all previous assignments and output this:

{"a":1}
{"a":2,"b":2}
{"a":3,"b":3,"c":3}
{"a":4,"b":4,"c":4,"d":4}
{"a":5,"b":5,"c":5,"d":5,"e":5}

When what I expect / want to finish with is:

{"a":"1","b":"2","c":"3","d":"4","e":"5"}

How do I achieve what I want?

kwah
  • 1,149
  • 1
  • 13
  • 27

2 Answers2

2

You need to create a function that returns a function that does what you want (this is just because of how closures work in JavaScript). This example should work.

var o = {};

var foo = [['a',1],['b',2],['c',3],['d',4],['e',5]];

var getFunc = function(val){
    return function() {
        return val; 
    }
};

for(var i = 0; i < 5; i++)
{
  var func = getFunc(foo[i][1]);
  o.__defineGetter__(foo[i][0], func);
}
console.info(JSON.stringify(o));
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • Thanks, I was able to modify this to my getter needs but the code in the OP was a heavily reduced case and I need more specific help. What should I do? ie, Should I ask another question or edit this one? – kwah Aug 24 '10 at 16:54
  • This question is already answered. I guess asking another question is ok. – gen_Eric Aug 24 '10 at 17:01
1

This is because of the way that closures work. Variables are scoped to the functions they are defined in. There is no such thing as a loop variable (unless you are using a version of JS that has the let keyword). As a result, at the end of the loop, the value of i is the same in all of the anonymous functions you defined. You can see this by outputting i at the end of the loop:

for(var i = 0; i < 5; i++)
{
  o.__defineGetter__(foo[i][0], function() {
    return foo[i][1]; 
  });
  console.info(JSON.stringify(o));
}
console.info(i); //outputs 5

EDIT: As pointed out, this is the same problem, as in this question: JavaScript closure inside loops – simple practical example

Community
  • 1
  • 1
Russell Leggett
  • 8,795
  • 3
  • 31
  • 45