0

Say I have a code-snippet:

dict = {"key":"elem"}
for (var elem in dict){
    someFunction(function(){
        anotherFunction(dict[elem]);
    })
}

Is elem still that temporary variable created in the for...in... statement when it is referenced at that third level, i.e. at anotherFunction(dict[elem])?

When it gets called in my code, I get an error saying that it returns undefined.

EDIT: could I somehow fix this with a this keyword somewhere?

kalaracey
  • 815
  • 1
  • 12
  • 28
  • A loop has no notion of a scope. What is the `dict` variable? Object or Array? – rxgx Jul 02 '12 at 22:55
  • 1
    There is only **one** variable named `elem` -- what does this imply about the *value* it evaluates to at the usage site? (Hint: *only new function scopes can introduce a new variables*.) Look for "javascript loop last value closure" or similar. –  Jul 02 '12 at 22:55
  • Your edit is nonsense, how can it b fixed with `this` somewhre? – gdoron Jul 02 '12 at 22:55
  • e.g. http://stackoverflow.com/questions/6425062/passing-functions-to-settimeout-in-a-loop-always-the-last-value , http://stackoverflow.com/questions/2520587/variable-in-javascript-callback-functions-always-gets-last-value-in-loop , http://stackoverflow.com/questions/6599157/why-always-the-last-reference-to-the-object-is-used-in-loop (this might not be *the* problem, bit is *a* problem) –  Jul 02 '12 at 22:58
  • Ok, sorry, dict is an object, say, defined as `dict = {"key" : "val"}` – kalaracey Jul 02 '12 at 23:05
  • FYI: `elem` is not a temporary value. As long as the scope object of `elem` exists, it will be available in that scope. – rxgx Jul 02 '12 at 23:10

4 Answers4

1

You are creating a closure over the anonymous function so it depends on what you do with the variable between setting it and using it.

var dict = {
    "a": "aaaaaaaaa",
    "b": "bbbbbbbbb",
    "c": "ccccccccc"
};

for (var elem in dict) {
    someFunction(function() {
        anotherFunction(dict[elem]);
    })
}

function anotherFunction(a) {
    console.log(a);
}

Async: The loop runs through before actually executing the code so elem winds up being the last key in the set. The last key gets used several times.

function someFunction(f) {   
    setTimeout(f, 500);
}

Synchronous: Each function runs in order, so each value gets printed out

function someFunction(f) {
    f();
}
Dennis
  • 32,200
  • 11
  • 64
  • 79
0

elem is defined your problem is that:

dict[elem]

returns undefind

gdoron
  • 147,333
  • 58
  • 291
  • 367
0

If you create a variable inside any statement the variable will still be scoped to the closest parent function, that's how JavaScript works. Scopes are functions. You should be able to use elem there though so your problem must be somewhere else as gdoron said.

Edit:

It seems that you're calling a function that takes another function as a parameter. Is that really what you want to do?

elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • The first part is true. I suspect the issue is related to not understand this (or just not having the right data, or not using a lexical variable or, ...) –  Jul 02 '12 at 23:01
0

To use the dict variable as the scope of anotherFunction, you need to reference dict as the scope of that function. Example:

for (var elem in dict) {
  someFunction(function(dict, elem) {
    return anotherFunction.call(dict, elem);
  }
}

In your anotherFunction structure, the usage of the this keyword would reference the dict object.

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call

rxgx
  • 5,089
  • 2
  • 35
  • 43