Introduction
Let's first look at a common example,
Func() {for (ten; i++) {SetTimeout (function () {Console.log (i)}, +)}}func ()
The result of the output is not our expected 0-9, but the output of 10 10. And when we var
change let
it, the result is 0-9.
Reason
var
The function scope is used, that is, for
the loop is var i
actually valid throughout the func
function. and setTimeout
the anonymous function (10) is able to access the same because of the reason of the closure, i
because they are deferred execution, so wait until console.log(i)
executed, i
is already 10.
In the past, we used to deal with this situation by using another function that would be i
loaded into its own function scope:
Helper(i) { setTimeout (function () { console.log (i) }, +)}func for(ten; i++ ) {Helper (i)}}func ()
In this way, although setTimeout
the anonymous function is still delayed, but helper
is called immediately ( helper(0), helper(1), ...
), and its parameters i
are held by its function scope (rather than func
held), so that each anonymous function through the closure of the access to the i
independent, the To be able to get 0-9
.
Why let is different
let
Is the new feature introduced by ES6, and the var
biggest difference is that it is a block-level scope, so the equivalent for
of each loop i
is independent, they are in the statement block (the loop body) at the end of the failure (of course, because the closure of the reason can still be setTimeout
accessed by anonymous functions), The anonymous function holds each scope instead of the i
same one.
The specific difference
Although the above explanation, but still have some vague feeling. Here's a look at how the behavior of block-level scopes and function scopes is different:
Different scope scopes
As the name implies, function scopes are useful in the functions in which they reside, and block-level scopes are only useful in their own code blocks, for example:
Func() { if (//access less than}func ()
Different behavior of variable promotion
var
and let
the variable promotion behavior is different, first understand what is called the variable promotion, that is
' Test ' func' in '}func ()
That is, all function declarations in a function var
are advanced to the head of the function, for the var
above code is equivalent to
' Test ' func' in '}func ()
And let
the performance is more rigorous, the same, let's declaration will be advanced, but if in this case try to access the uninitialized k
, will throw one ReferenceError
. We call this feature \ "Temporary Dead Zone \", which avoids some weird mistakes.
Also, because of the scope, let
the declaration takes effect early in the code block.
Verify the idea above
So, how to verify that the for
loops are not the same each time they are executed i
, but also very simple, we put i
the declaration for
outside:
Func() {Let I ten; i++) {SetTimeout (function () {Console.log (i)}, +)}}func ()
Get 10 more 10 again, var
same as when used (because scopes are func
inside functions).
Summarize
let
Behave more than var
expected, the rules are stricter, so we should use and replace them as much as possible, so let
that the const
var
code does not behave strangely at the beginning.
The Var and let in JavaScript