1

This is a simplified version of my function. The problem is that I get 2 both times in the alert. I believe this is a variable scope problem, but I can't seem to figure it out.

var someObj = {"a" : 1, "b" : 2};

function getData(obj){
  var bunchOfFunctions = {};  
    for(var key in obj){
      value = obj[key];
        bunchOfFunctions[key] = function(){
            alert(value);
        }
    }
  return bunchOfFunctions;
}

var functs = getData(someObj);
for(var key in functs){
    functs[key]();
}

Here is a jsfiddle http://jsfiddle.net/earlonrails/q4d66/

earlonrails
  • 4,966
  • 3
  • 32
  • 47

3 Answers3

2

It's kind-of a scope problem. The issue is that each function in the bunch shares the same variable "value". In your case, you forgot to declare "value" with var, so it's a global variable.

Even if you did use var, however, you'd have the same problem.

The trick is to introduce a new layer of scope by wrapping the creation of the function in yet another function.

    bunchOfFunctions[key] = function(valueCopy) {
      return function() {
        alert(valueCopy);
      };
    }(value);
Pointy
  • 405,095
  • 59
  • 585
  • 614
2

Fiddle of below answer

You will have to replace

  value = obj[key];
  bunchOfFunctions[key] = function(){
      alert(value);
  }

With:

  value = obj[key];
  bunchOfFunctions[key] = (function(value) { return function() {
      alert(value);
  } })(value)

This is because the value variable keeps changing, so once the loop is done running value is 2. What this code does is call a function with value, and that function returns another function. The other function it returns, however, now has the correct value because it is in its own scope.

tckmn
  • 57,719
  • 27
  • 114
  • 156
0

When the function containing the alert statement runs, it only see the value of the last interaction of the for statement

The solution to avoid this problem is:

var someObj = {"a" : 1, "b" : 2};

function getData(obj){
  var bunchOfFunctions = {};  
  for(var key in obj){
    var value = obj[key];
    bunchOfFunctions[key] = (function(x){
        return function() {
            alert(x);
        }
    })(value)
  }
  return bunchOfFunctions;
}

var functs = getData(someObj);
for(var key in functs){
   functs[key]();
}
Rodrigo Villalba Zayas
  • 5,326
  • 2
  • 23
  • 36