Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #31442

Re: Confused about let and var

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: Confused about let and var
Date 2016-09-24 18:12 +0200
Organization PointedEars Software (PES)
Message-ID <1759466.oMNUckLgyt@PointedEars.de> (permalink)
References <57e4e5d9$0$876$e4fe514c@news.xs4all.nl>

Show all headers | View raw


Erwin Moller wrote:

> […] Also, we can keep the scope around the loop cleaner by moving the code
> that creates the new elements into the scope of each loop.

Not only the loop, but also the *Block* statement associated with the loop 
statement.  See below.
 
> […]
> Compare it to the following code:
> 
> var list = document.getElementById("list");
> let i = 1;
> while (i <= 5) {
>    let item = document.createElement("li");
>    item.appendChild(document.createTextNode("Item " + i));
> 
>    item.onclick = function (ev) {
>      console.log("Item " + i + " is clicked.");
>    };
>    list.appendChild(item);
>    i++;
> }
> 
> In the above code 'let' behaves as 'var' and all clicks will result in
> "Item 6 is clicked".
> 
> (I am not sure I should use 'closure' in this context, but the code
> behaves that way.)

“Closure” is the correct term here.

<https://en.wikipedia.org/wiki/Closure_(computer_programming)>
 
> So what happens differently between these two codepieces?
> 1) let i = 1;
> while (i <= 5) {...
> 
> 
> and
> 
> 2) for (let i = 1; i <= 5; i++) {...
> 
> 
> Is the use of 'let' in the for-loop considered INSIDE the block?

“var” does variable scoping based on the VariableEnvironment of execution 
contexts.  “let” enforces *lexical* *block* scoping or, IOW, scoping “to the 
running execution context’s LexicalEnvironment” (ECMAScript Language 
Specification [ES] 6.0 and 7.0, § 13.3.1).

Different to a declaration with “var”, a variable declared with “let” is 
only defined in the same block and inner blocks (like e.g. Python¹).  If you 
declare a variable with “let” outside of a block, then it works like “var” 
inside the block because it is bound to the outer block’s lexical 
environment.

_______
¹  Different to “var” and to Python, there can only be one “let” declaration 
   for the same variable in the same block/LexicalEnvironment.  Otherwise it 
   is a syntax error (“SyntaxError: Identifier 'foo' has already been
   declared”).  Note that this is purely syntax-related: You can have 
   one declaration with “let” for the same variable inside a loop, but not 
   more.  [AFAIK, Python does not have a variable declaration without
   explicit initialization, so there is no obvious difference between a 
   declaration with initialization and a simple assignment.  PHP and a
   number of other scripting languages exhibit the same issue.]

> (Because literally, it is not).

The difference between the “while” statement and the “for” statement 
(variants that do not contain the “in” or “of” keyword) is that the latter 
has an initialization part that allows for variable declarations.  
Therefore, there is a special “for” statement where with a *lexical* 
declaration the variable can be bound to the “for” statement instead of the 
adjacent block, and still, since *semantically* the adjacent block has to 
have access to the variables declared in the “for” statement, it works as if 
the “for” statement would create a block of its own (ES 6.0 and 7.0, 
§ 13.7.4).

A most interesting thing happens when you use “for (let …)” and move the 
post-increment operation into the block: you end up with the console saying 
“Item 2 is clicked” when you clicked “Item 1” and so on.  Intuitively you 
would think that an increment in the “for” statement or in the adjacent 
block were equivalent; but that is not so if the variable was declared with 
“let” in the “for” statement.

If you find “let” confusing, I suggest that you do not use it.  That would 
have the additional advantage of writing backwards-compatible code.

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

Confused about let and var Erwin Moller <erwinmollerusenet@xs4all.nl> - 2016-09-23 10:20 +0200
  Re: Confused about let and var Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-23 19:26 +0100
  Re: Confused about let and var Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-09-24 18:12 +0200

csiph-web