为什么在Javascript中,范围是功能级别,而不是块级别?

时间:2010-04-27 17:50:13

标签: javascript scope

在问题中

Javascript infamous Loop issue?

Christoph's接受的答案

  

JavaScript的范围是   功能级,而不是块级

如果Javascript的作用域是块级的,那么臭名昭着的循环问题是否仍会发生?或者是否会有一种不同的(更容易的)修复方式?

是否与其他语言相对,使用{会启动新范围?

3 个答案:

答案 0 :(得分:3)

我找到了答案:

Javascript 1.7及更高版本支持块级范围,Firefox 3.0及更高版本支持它。 (见http://en.wikipedia.org/wiki/Javascript#Versions

我使用Firefox 3.5.9尝试了以下代码:
请注意,使用关键字let,这将创建块级范围。

<a href="#" id="link1">ha link 1</a>
<a href="#" id="link2">ha link 2</a>
<a href="#" id="link3">ha link 3</a>
<a href="#" id="link4">ha link 4</a>
<a href="#" id="link5">ha link 5</a>


<script type="application/javascript;version=1.7"/>  

    for (i = 1; i <=5; i++) {
        let x = i;
        document.getElementById('link' + i).onclick = function() { alert(x); return false; }
    }

</script>

果然,创建了一个新的范围,其中包含一个新的x。执行alert(x)的匿名函数捕获此范围(整个范围链)并记住它,从而形成闭包。当调用此匿名函数时,范围就在那里,当它查找x时,当然x在该范围内分别为1,2,3,4,5。尝试将let更改为var,然后再次出现臭名昭着的老问题,因为没有创建新范围。

答案 1 :(得分:1)

如果块创建了范围(用于闭包),那么这将像后来在StackOverflow上发布问题的人认为它可能有效一样有效:

for (var i = 0; i < thing.length; ++i) {
  var element = $('#elem' + i); // making this up randomly here
  setTimeout(function() { doSomething(element); }, 100);
}

这样可行,因为循环体的每次迭代都会(可能)创建一个新的范围,从而创建一个新的“元素”。事实上,没有创建新范围的事实意味着通过循环的进度实例化的每个函数共享相同的“元素”变量,因此代码无法正常工作,另一个StackOverflow javascript问题是生。

答案 2 :(得分:0)

基本上,它是一种说法,通过第一个设置获得的值是一个'指针' - 在调用方法时对变量值的引用。在第二个实例中,值是'copy',而不是'pointer',因此每个实例都有自己的值。

这是假设我已经正确地阅读了您的问题。