for() 循环中声明的 Javascript 变量的范围是多少?

发布于 2024-08-30 07:12:31 字数 682 浏览 11 评论 0原文

查看以下 HTML/Javascript 代码片段:

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

此输出:

3, 3, 3, 0, 1, 2

这不是我所期望的 - 我期望输出 0, 1, 2, 0, 1, 2,

I (错误地) )假设被推入数组的匿名函数将表现为闭包,捕获创建函数时分配的 i 值 - 但实际上似乎 i表现为全局变量。

谁能解释一下此代码示例中的 i 范围发生了什么,以及为什么匿名函数没有捕获其值?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的呼吸 2024-09-06 07:12:31

作用域是定义变量的函数(除了没有作用域,所以它是全局的)。

您传递的匿名函数正在访问父函数(同样是全局)范围中定义的变量。

你需要一个真正的关闭。

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

        }
    }(i)
);

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)
);
Saygoodbye 2024-09-06 07:12:31

在 Javasript 中,唯一“有趣”的词法作用域边界是函数体。函数中任何地方声明的任何内容(好吧,除了另一个嵌套函数之外的任何地方!)都位于相同的作用域。声明的解释方式也有一些奇怪的事情。

您的匿名函数确实充当闭包,但实例化的每个函数将共享相同的“i”。我使用的一个技巧是添加另一层功能:

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

在某个时候,希望所有浏览器都支持新的“let”语句,这是一种更短、看起来不那么奇怪的方法,可以完成基本相同的事情。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文