Unusual behavior of variables captured by a clusure in a for

Asked

Viewed 48 times

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 It’s exactly the same thing, only properties instead of numerical indexes. I voted to close as duplicate.

  • 2

    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 (or dummy) created within the for is the same for all iterations of for. When the for changes, the variable changes. To capture that value, see the penultimate example of my answer to the double question.

  • 1

    @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.

  • 1

    @bfavaretto Truth, I expressed myself badly. I meant that these variables do not have their fixed value.

1 answer

2


Browser other questions tagged

You are not signed in. Login or sign up in order to post.