코드를 분석해보자
let x = true;
let y = false;
function a() {
let a = 5;
y = true;
if(x) {
let a = 2;
for(let i = 0; i < a; i++) {
console.log(i);
}
if(!y) {
console.log('hi');
}
}
c(); // 레퍼런스 에러
}
a();
const c = () => {}
const e = (a, b) => { return a + b };
e(5, 2);

- 우선 호출스택에 anonymouse, a함수가 쌓인다
- anonymouse스코프에 함수a, x, y가 선언 되고, 값이 할당된다
- a함수가 호출 스택에 쌓인다
- a함수의 스코프에 a변수가 선언되고 값이 할당된다

- a함수에 y=false; 코드를 만나면 우선 a스코프에서 y를 찾고 y가 없으면 상위 스코프로 올라가 값이 있으면 값을 새로 할당한다
- a함수의 if가 실행이 될때 if 스코프에서 a변수가 선언되고 할당된다
- if문에 for문은 반복문이 실행 될때마다 새로운 스코프를 만든다
- if(!y)문은 실행이 되지 않기 때문에 무시한다
- a함수에서 c함수를 호출 햇지만 c함수는 const로 선언하여 아직 할당이 안되어 TDZ에서 호출 하엿으로 refrence에러가 생긴다

- a함수에 실행이 끝나면 호출스택에서 사라진다
- const c=()=>{}, const e=(a,b)=>{return a+b} 을 만다 anony에 선언된다
- e함수가 호출되어 호출스택에 e함수가 생긴다
- e함수도 실행이 끝나면 호출스택에서 사라지고, 더이상 실행할 함수가 없으면 anonymouse도 호출 스택에서 사라진다