실험 1 — strict 모드: 블록 안 함수는 블록 최상단으로 호이스팅
선언문보다 먼저 호출해도 동작합니다. TDZ가 없어요.
코드
Run
"use strict"; { foo(); // 선언문보다 위에서 호출 function foo() { console.log("foo() 실행됨"); } foo(); // 선언문 아래에서도 호출 } try { foo(); // 블록 밖에서는? } catch (e) { console.log("블록 밖:", e.constructor.name, "-", e.message); }
실험 2 — let / const는 다르다 (TDZ 존재)
함수 선언문과 달리 let/const는 선언 위치 전에 접근하면 ReferenceError가 나요.
코드
Run
"use strict"; { try { bar(); // TDZ! 아직 초기화 안 됨 } catch (e) { console.log("bar() 호출:", e.constructor.name, "-", e.message); } const bar = () => console.log("bar 실행"); baz(); // 함수 선언문은 OK function baz() { console.log("baz 실행"); } }
실험 3 — 조건부 함수 정의: 함수 선언문 vs const + 표현식
strict 모드 기준. 함수 선언문은 블록 스코프에 갇히고, const + 표현식은 의도대로 동작해요.
코드
Run
"use strict"; const isDev = true; // ❌ 패턴 1: 함수 선언문 — 둘 다 블록 스코프에 갇혀서 밖에서 안 보임 if (isDev) { function log(msg) { console.log("[DEV]", msg); } } else { function log(msg) { /* no-op */ } } try { log("hello"); } catch (e) { console.log("선언문 패턴:", e.constructor.name, "-", e.message); } // ✅ 패턴 2: const + 함수 표현식 — 깔끔하게 동작 const log2 = isDev ? (msg) => console.log("[DEV]", msg) : (msg) => {}; log2("표현식 패턴: 정상 동작");