最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

What's the scope of a Javascript variable declared in a for() loop? - Stack Overflow

programmeradmin5浏览0评论

Check out the following snippet of HTML/Javascript code:

<html>
<head>
<script type="text/javascript">
var alerts = [];
for(var i = 0; i < 3; i++) {
    alerts.push(function() { document.write(i + ', '); });
}

for (var j = 0; j < 3; j++) {
    (alerts[j])();
}

for (var i = 0; i < 3; i++) {
    (alerts[i])();
}
</script>
</head><body></body></html>

This outputs:

3, 3, 3, 0, 1, 2

which isn't what I was expecting - I was expecting the output 0, 1, 2, 0, 1, 2,

I (incorrectly) assumed that the anonymous function being pushed into the array would behave as a closure, capturing the value of i that's assigned when the function is created - but it actually appears that i is behaving as a global variable.

Can anyone explain what's happening to the scope of i in this code example, and why the anonymous function isn't capturing its value?

Check out the following snippet of HTML/Javascript code:

<html>
<head>
<script type="text/javascript">
var alerts = [];
for(var i = 0; i < 3; i++) {
    alerts.push(function() { document.write(i + ', '); });
}

for (var j = 0; j < 3; j++) {
    (alerts[j])();
}

for (var i = 0; i < 3; i++) {
    (alerts[i])();
}
</script>
</head><body></body></html>

This outputs:

3, 3, 3, 0, 1, 2

which isn't what I was expecting - I was expecting the output 0, 1, 2, 0, 1, 2,

I (incorrectly) assumed that the anonymous function being pushed into the array would behave as a closure, capturing the value of i that's assigned when the function is created - but it actually appears that i is behaving as a global variable.

Can anyone explain what's happening to the scope of i in this code example, and why the anonymous function isn't capturing its value?

Share Improve this question asked Apr 28, 2010 at 21:57 Dylan BeattieDylan Beattie 54.2k35 gold badges136 silver badges200 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

The scope is the function that the variable is defined in (except there isn't one, so it is global).

The anonymous function you are passing is accessing the variable defined in the parent function's (again global) scope.

You need an actual closure.

alerts.push(
    function (foo) { 
        return function() { 
            document.write(foo + ', ');

        }
    }(i)
);

In Javasript, the only "interesting" lexical scope boundary is the function body. Anything declared anywhere in a function (well, anywhere other than another nested function!) is at the same scope. There are also some weird things about the way that the declarations are interpreted.

Your anonymous function does act as a closure, but each function instantiated will share the same "i". A trick I use is to add another layer of function:

for (var i = 0; i < whatever; i++) {
  (function(idaho) {
    whatever(function() { alert("my own private " + idaho); });
  })(i);
}

At somepoint hopefully all the browsers will support the new "let" statement, which is a shorter, less weird-looking way to do basically the same thing.

发布评论

评论列表(0)

  1. 暂无评论