It seems that in language like C, Java, and Ruby (as opposed to Javascript), a new scope is created for each i开发者_如何学Goteration of a loop block, and the local variable defined for the loop is actually made into a local variable every single time and recorded in this new scope?
For example, in Ruby:
p RUBY_VERSION
$foo = []
(1..5).each do |i|
$foo[i] = lambda { p i }
end
(1..5).each do |j|
$foo[j].call()
end
the print out is:
[MacBook01:~] $ ruby scope.rb
"1.8.6"
1
2
3
4
5
[MacBook01:~] $
So, it looks like when a new scope is created, a new local copy of i
is also created and recorded in this new scope, so that when the function is executed at a later time, the "i" is found in those scope chains as 1, 2, 3, 4, 5 respectively. Is this true? (It sounds like a heavy operation).
Contrast that with
p RUBY_VERSION
$foo = []
i = 0
(1..5).each do |i|
$foo[i] = lambda { p i }
end
(1..5).each do |j|
$foo[j].call()
end
This time, the i
is defined before entering the loop, so Ruby 1.8.6 will not put this i
in the new scope created for the loop block, and therefore when the i
is looked up in the scope chain, it always refer to the i
that was in the outside scope, and give 5 every time:
[MacBook01:~] $ ruby scope2.rb
"1.8.6"
5
5
5
5
5
[MacBook01:~] $
I heard that in Ruby 1.9, i
will be treated as a local defined for the loop even when there is an i
defined earlier?
The operation of creating a new scope, creating a new local copy of i
each time through the loop seems heavy, as it seems it wouldn't have matter if we are not invoking the functions at a later time. So when the functions don't need to be invoked at a later time, could the interpreter and the compiler to C / Java try to optimize it so that there is no local copy of i
each time?
This is similar to the topic discussed here: http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/ . In some programming languages, when you loop over a variable, the body of the loop construct is bound to one variable that increments. In others, a new loop variable is instantiated per iteration of the loop.
As for lexical scope, note that in JavaScript, functions are the only constructs that form scopes (braces for if
, while
, for
, etc. do not). In C/C++, any pair of braces forms a scope.
精彩评论