Why does it matter that in Javascript, scope is function-level, not block-level?
In the question
Javascript infamous Loop issue?
the accepted ans开发者_开发问答wer from Christoph's says
JavaScript's scopes are function-level, not block-level
What if Javascript's scopes are block-level, then would the Infamous Loop problem still occur? Or will there be a different (and easier) way of fixing it?
Is it as opposed to other languages, where using a {
would start a new scope?
I found an answer:
Javascript 1.7 and above supports block-level scope, and Firefox 3.0 and above supports it. (See http://en.wikipedia.org/wiki/Javascript#Versions )
I tried the following code using Firefox 3.5.9:
Note that the keyword let
is used, which will create a block-level scope.
<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>
Sure enough, a new scope is created, with a new x
in it. The anonymous function that does the alert(x)
captures this scope (the whole scope chain) and remembers it, thus forming the closure. When this anonymous function is invoked, the scope is there, and when it looks for x
, sure enough, the x
is in that scope as 1, 2, 3, 4, 5 respectively. Try and change the let
into a var
and you get the infamous old problem again, because no new scope is created.
If blocks created scopes (for closures), then this would work the way people who later post a question on StackOverflow think it might work:
for (var i = 0; i < thing.length; ++i) {
var element = $('#elem' + i); // making this up randomly here
setTimeout(function() { doSomething(element); }, 100);
}
That would work because each iteration of the loop body would (probably) create a new scope, and thus a new "element". As it is, the fact that no new scope is created means that each function instantiated through the progress of the loop shares the same "element" variable, and thus the code doesn't work properly and another StackOverflow javascript
question is born.
Basically, it's a way of saying the value obtained via the first setup is a 'pointer' - a reference to the value of the variable when the method is invoked. In the second instance, the value is a 'copy', not a 'pointer', so each instance has it's own value.
That's assuming I have read your question right.
精彩评论