>しかし、下記の2つのfor文でxについて2回宣言しているように思うのですが、
>エラーにならないのは何故でしょうか。
これは、letで宣言された変数は、ブロックスコープを持つからです。
for文の第1式で宣言された変数は、for文のブロックの中だけのスコープを持ちます。
よって、以下のプログラムは、
for (let i = 0; i < 10; i++) {
console.log("i.." + i);
}
console.log("i.." + i);
「i..0」から「i..9」までは表示しますが、最後の、for文の後のconsole.log()の
ところで、以下のエラーを出します。
Uncaught ReferenceError: i is not defined
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let
| let 文はブロックスコープのローカル変数を宣言します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for
| let で宣言された変数は文内のローカル変数になります。
このあたりは、JavaとかC++とかC#とかC99とかと同じで、JavaScriptもletが導入されて
ようやく「普通の言語になった」感があります。
昔のJavaScriptではvarしか使えませんでしたが、varによる変数宣言は関数スコープで、
クロージャという仕組みと相俟って、初心者には訳の分からない結果を出すことが
ありました……
例)
https://teratail.com/questions/205789