練習問題①:基本的な let 宣言
問題:以下のコードを実行したとき、コンソールに出力される内容は何でしょう?
let name = "Taro";
name = "Jiro";
console.log(name);
解答:
Jiro
解説:let
は再代入可能なので "Taro"
→ "Jiro"
に上書きされ、"Jiro"
が出力される。
let name = "Taro"; // letで変数nameを宣言し、「Taro」を代入する
name = "Jiro"; // 変数nameに新しい値「Jiro」を再代入する(letは再代入が可能)
console.log(name); // コンソールに「Jiro」と表示される
練習問題②:let と var のスコープの違い
問題:以下のコードの出力結果は?
function test() {
if (true) {
let a = 10;
}
console.log(a);
}
test();
解答:
ReferenceError: a is not defined
解説:let
は ブロックスコープ。if
ブロックの外からは参照できないため、エラーになる。
function test() { // testという関数を定義する
if (true) { // 常にtrueなので、ifブロックの中は必ず実行される
let a = 10; // letで変数aを宣言し、10を代入(※このブロック内でのみ有効)
}
console.log(a); // エラー!aはifブロックの外なのでスコープ外。ReferenceErrorになる
}
test(); // 関数testを実行する
練習問題③:let の再宣言は可能か?
問題:以下のコードを実行したときにエラーになりますか?
let x = 1;
let x = 2;
console.log(x);
解答:
SyntaxError: Identifier 'x' has already been declared
解説:同じスコープ内で let
変数を 再宣言することはできない。再代入はOKだが、再宣言はNG。
let x = 1; // letで変数xを宣言し、1を代入する
let x = 2; // ❌エラー!同じスコープ内でletによる再宣言はできない
console.log(x); // この行には到達せず、上の行で「SyntaxError」が発生する
練習問題④:for ループでの let のスコープ
問題:以下のコードの出力は?
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
解答:
0
1
2
解説:let
によって i
は 各ループごとに新しいスコープで保持される。var
では全て同じ変数を参照してしまうため違いが出る。
for (let i = 0; i < 3; i++) { // iを0から始めて、iが3未満の間ループする。iはletでブロックスコープ。
setTimeout(() => console.log(i), 100); // 100ミリ秒後に現在のiを表示する関数をスケジュールする
}
練習問題⑤:let の初期化タイミング
問題:以下のコードはエラーになりますか?
console.log(y);
let y = 5;
解答:
ReferenceError: Cannot access 'y' before initialization
解説:let
は ホイスティングされるが、初期化されるまで使えない。この状態を「一時的デッドゾーン(TDZ)」と呼ぶ。
練習問題⑥:ブロックスコープの理解
問題:以下のコードの出力は?
{
let message = "Hello";
}
console.log(message);
解答:
ReferenceError: message is not defined
解説:let
は {}(ブロック)内限定で有効なので、外部からアクセスできない。
{
let message = "Hello"; // ✅ ブロック内で変数 message を宣言・初期化(スコープはこの中のみ)
}
console.log(message); // ❌ ReferenceError: message is not defined(スコープの外なのでアクセス不可)
練習問題⑦:グローバル変数としての let
問題:以下のコードを実行後、window.count
にアクセスすると何が表示される?
let count = 5;
console.log(window.count);
解答:
undefined
解説:var
はグローバルスコープで宣言すると window
オブジェクトに属するが、let
は属さない。
let count = 5; // グローバルスコープに変数 count を宣言(ただし let を使用)
console.log(window.count); // undefined(let で宣言した変数は window オブジェクトのプロパティにはならない)
練習問題⑧:関数内スコープと let
問題:次のコードの出力は?
function outer() {
let a = "outer";
function inner() {
let a = "inner";
console.log(a);
}
inner();
console.log(a);
}
outer();
解答:
inner
outer
解説:let
で定義された変数は関数・ブロックごとに独立。inner
の中の a
と outer
の a
は別物。
function outer() {
let a = "outer"; // outer関数の中で変数aを定義し、"outer"という文字列を代入
function inner() {
let a = "inner"; // inner関数の中で、同じ名前の変数aを再び宣言(これはouterのaとは別物)
console.log(a); // inner関数内のaを参照 → "inner"と出力される(内側のスコープが優先される)
}
inner(); // inner関数を呼び出す(ここで"inner"が出力される)
console.log(a); // outer関数内のaを参照 → "outer"と出力される
}
outer(); // outer関数を実行 → inner()の"inner"と、outerの"outer"が順に出力される
練習問題⑨:複数の let 宣言(異なるスコープ)
問題:以下のコードの結果は?
let color = "red";
if (true) {
let color = "blue";
console.log(color);
}
console.log(color);
解答:
blue
red
解説:let
での再宣言は スコープが異なれば可能。if
ブロック内と外で color
は別の変数。
let color = "red"; // グローバルまたは関数スコープ内で color を "red" として宣言
if (true) {
let color = "blue"; // if ブロック内で新しく color を "blue" として再宣言(これは別の変数)
console.log(color); // ブロック内の color を参照 → "blue" と出力される
}
console.log(color); // ブロック外の color を参照 → "red" と出力される
練習問題⑩:条件分岐と let のスコープ
問題:次のコードを実行するとどうなるでしょう?
let flag = true;
if (flag) {
let message = "ON";
console.log("Inside if:", message);
}
console.log("Outside if:", message);
解答:
Inside if: ON
ReferenceError: message is not defined
解説:let
で宣言された変数は ブロック({ })の中だけで有効。
そのため、if
文の中で宣言された message
は外側では参照できず、エラーになります。
let flag = true; // 変数 flag を true として宣言
if (flag) {
let message = "ON!"; // if ブロック内で message を宣言(スコープはこのブロック内のみ)
console.log("Inside if:", message); // → "Inside if: ON!" が表示される
}
console.log("Outside if:", message); // ❌ エラー:message は if ブロックの外では参照できない
コメント