2
Consider an object obj
whichever:
obj = {q: 1, w: 2, e: 3, r: 4, t: 5, y: 6};
Now I’m iterating under the object keys and creating an anonymous function that uses this key:
list = []
for (var key in obj) {
list.push(function() {
return key;
});
}
But it doesn’t work: console.log(list[0]()) // isso mostra "y"
. It’s like the variable key
used is always for the last iteration and not for the iteration that created the function. Modifying thus does not solve the problem:
list = []
for (var key in obj) {
var dummy = key;
list.push(function() {
return dummy;
});
}
Even though I created a different variable in each iteration and referred to its value specifically, the result is the same. Not even write something like the following works.
list = []
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; ++i) {
var key = keys[i];
list.push(function() {
return key;
});
}
Why? What’s going on here? How to write a code that does the proposed?
It seems the same problem of a question I asked for some time. Or not?
– utluiz
@utluiz It’s exactly the same thing, only properties instead of numerical indexes. I voted to close as duplicate.
– mgibsonbr
And just so we don’t leave unanswered, these variables nay are captured: the lexical scope of Javascript is by function, not by block: the
key
(ordummy
) created within thefor
is the same for all iterations offor
. When thefor
changes, the variable changes. To capture that value, see the penultimate example of my answer to the double question.– mgibsonbr
@mgibsonbr I disagree with you in one detail: the variables are rather captured by the anonymous functions of the example. The entire outside scope (and here I suppose the global scope) is captured, including the variables in question. As you yourself once said in a reply (if I remember correctly), closures in js are nothing more than a consequence of the way the scope string works in the language.
– bfavaretto
@bfavaretto Truth, I expressed myself badly. I meant that these variables do not have their fixed value.
– mgibsonbr