실행 컨텍스트를 이해하기 위해서 알아야할 개념이 많이 있습니다.
근데 공부해도 뒤 돌아서면 까먹는 나란 아이.. 비정상 일까요..?
이제는 더이상 물러날 곳이 없다..!
이번에는 실행 컨텍스트를 공부하며 함께 등장했던 개념들을 차근차근 정리해보려 합니다.
자바스크립트에서 코드가 실행되는 전체적인 환경입니다.
→ 환경 :코드 실행에 영향을 주는 조건, 변수, 스코프, this 등을 의미합니다.
함수가 호출될 때 실행 컨텍스트가 생성되어 콜 스택(Call Stack)에 쌓이고, 실행 흐름이 관리됩니다.
콜 스택은 하나가 존재하고, 각 함수 호출마다 새로운 실행 컨텍스트가 생성되어 기존 콜 스택에 푸시(push) 콜 스택에 쌓입니다.
콜 스택은 실행 순서를 관리하며, 컨텍스트가 끝나면 스택에서 팝(pop)됩니다.



var, 함수 선언문은 먼저 변수 환경에 등록되기 때문에var와 함수 선언문은 호이스팅이 빠르게 일어납니다.
환경 레코드 Environment Record
let, const), 함수 표현식, 매개변수 등이 실제로 저장되는 객체입니다. 외부 환경 참조 Outer Environment Reference
렉시컬 환경은 코드 실행 중 계속 변하는 활성 상태의 환경입니다.
let, const는 TDZ(Temporal Dead Zone) 상태도 이 환경 레코드에서 관리합니다.
⇒ 실행 중 변수가 업데이트되면 모두 렉시컬 환경에서 처리합니다.

this는 실행 컨텍스트에 따라 참조하는 대상이 달라지는 동적 바인딩입니다.
⇒ 렉시컬 환경은 “코드가 어디에서 작성되었는지”로 결정되는 반면,
this는 “함수가 어떻게 호출되었는지”에 의해 결정되기 때문입니다.
즉, 동일한 위치에 정의된 함수도 호출 방식이 달라지면 this가 달라질 수 있습니다.
전역 컨텍스트는 2가지 환경 기록을 가집니다.
var, 함수 선언문이 여기에 바인딩 됩니다.var a = 1를 작성하면, window.a로 접근이 가능합니다. let , const 변수가 여기에 저장됩니다.var a = 1를 작성하면, window.a로 접근이 불가능합니다. 함수 컨텍스트에서 this는 함수 호출 방식에 따라 달라집니다.
일반 함수 호출
func()
this는 전역 객체입니다. 그러나 strict 모드에서는 this는 undefined가 됩니다. 객체의 메서드로 호출
obj.method()
this는 해당 객체(obj)가 됩니다. 생성자 함수 호출
new Person()
this는 새로 만들어진 객체가 됩니다. 화살표 함수
() => {}
this를 그대로 가져오기 때문에 새로 만들지 않습니다.this는 obj가 됩니다.const obj = {
name: "Alice",
greet: function() {
console.log(this.name);
}
};
obj.greet(); // Alice
const obj = {
name: 'JavaScript',
getName: function() {
return this.name;
}
};
console.log(obj.getName()); // 'JavaScript'
const getName = obj.getName;
console.log(getName()); // undefined => Why? 일반 함수는 기본적으로 전역 객체를 this로 참조 왜 화살표 함수의 this만 상위 스코프를 가져오는가?
일반 함수는 호출될 때마다this가 새로 만들지만, 화살표 함수는this를 새로 만들지 않습니다.
왜냐하면 화살표 함수는 콜백, 이벤트, 비동기 코드에서this가 혼동되는 문제를 해결하기 위해 만들어졌기 때문입니다.

호이스팅이란 변수와 함수 선언이 코드의 최상단으로 끌어올려지는 현상입니다.
자바스크립트 엔진은 실행 컨텍스트를 생성할 때 소스 코드를 먼저 스캔하여 변수 및 함수 선언을 수집하고,
환경 레코드(Environment Record)에 등록하기 때문에 발생합니다.
var → undefined로 초기화 후 변수 환경에 등록됩니다. let, const → 렉시컬 환경에 선언만 등록되고 초기화 전까지 TDZ상태가 됩니다. 
this는 어떤 스코프의 this인가?"를 찾는 단계입니다.console.log(hoisting); // undefined
var hoisting = '호이스팅';
console.log(hoisting); // 호이스팅
변수 hoisting는 선언 전에 끌어올려져 첫 번째 console.log에서 접근 가능합니다

undefined 값 바인딩let, const
console.log(hoisting); // Reference Error
const hoisting = '호이스팅';

let, const로 선언된 변수는 Temporal Dead Zone(TDZ)에 들어가며, 초기화 전에는 접근이 불가능합니다. Temporal Dead Zone : let, const로 선언했을 때, 선언 이전에 식별자를 참조할 수 없는 구역함수 선언
/* Global */
study() // TypeError: 존재하지만 함수가 아닐 때
var study = () =>{
// do study
};
study는 undefined입니다. /* Global */
study() // Reference Error :변수가 존재하지 않을 때
const study = () =>{
// do study
};
const로 선언시, 환경레코드에 기록된 값이 없어 Reference Error 발생함수 표현
⇒ 함수 표현식 : 변수에 함수를 담아서 함수를 선언하는 방식
→ 함수를 변수에 담고 있기 때문에 변수 호이스팅과 똑같이 동작합니다.
/* Global */
study() // 실행함
function study(){
// do study
};
동기 함수는 실행되면 → 실행 컨텍스트 생성 → 콜 스택 쌓임 → 코드 실행 → 컨텍스트 제거 됩니다.
비동기 함수는 어떻게 실행컨텍스트가 실행되는걸까요?
콜백 큐에 등록됩니다.
콜백 큐는 비동기 함수의 콜백들이 대기하는 공간으로 타이머, 이벤트 등 실행 준비가 된 함수들이 이곳에 들어갑니다.
이벤트 루프(Event Loop)를 통해 콜백 함수가 실행 컨텍스트 콜 스택에 올라가고 실행 컨텍스트가 생성됩니다.
이벤트 루프는 콜 스택이 비었는지 계속 확인하며 콜 스택이 비어 있으면 콜백 큐에서 함수를 하나씩 꺼내 콜 스택에 올립니다.
실행 컨텍스트가 생성되어 함수가 실행됩니다.
비동기 이벤트 발생 → 콜백 큐 등록 → 콜 스택 비면 이벤트 루프가 콜백 스택에 올림 → 실행 컨텍스트 생성
setTimeout(() => {
console.log('Hello, World!');
}, 1000);
console.log('Synchronous Code');
setTimeout 호출 → 브라우저/Node.js가 타이머를 등록
콜백 함수(() => console.log('Hello, World!'))는 즉시 실행되지 않고
콜백 큐(Callback Queue)에 등록
현재 실행 컨텍스트(전역 컨텍스트)는 동기 코드 실행 후 종료 → 콜스택 비워짐
이벤트 루프(Event Loop)가 콜백 큐를 확인 → 콜백을 콜스택으로 올려서 실행 컨텍스트 생성 → 실행
함수가 자신이 선언될 때의 렉시컬 환경을 기억하는 것으로, 함수가 실행된 이후에도 외부 변수에 접근 가능 합니다.
자바스크립트에서는 함수가 생성될때마다 클로저가 생성됩니다. 각각의 함수가 자신만의 클로저를 갖습니다.
실행 컨텍스트가 종료된 이후에도 변수에 접근 가능합니다.
예시코드
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
실행 컨텍스트는 자바스크립트가 코드를 실행할 때 변수, 함수 선언, this, 스코프 등의 정보를 관리하는 환경 객체입니다. 전역 코드가 실행될 때 전역 실행 컨텍스트가 생성되고, 함수가 호출될 때마다 새로운 함수 실행 컨텍스트가 만들어집니다. 이 컨텍스트들은 콜 스택을 통해 순서대로 실행되며, 실행 흐름을 관리합니다. 실행 컨텍스트는 변수 환경, 렉시컬 환경, 그리고 this 바인딩으로 구성되어 있어, 변수 호이스팅, 스코프 체인, TDZ와 같은 규칙을 관리하고, this는 호출 방식에 따라 달라집니다. 자바스크립트 엔진은 이러한 정보를 활용해 변수를 어디서 찾고 어떤 순서로 코드를 실행할지 결정합니다.
최대한 시각화하려고 했는데요 ㅠㅠ
이 친구들,,, 생각보다 호락호락하지 않군여..
이벤트 루프와 비동기를 좀 더 보충해서 공부해야될 것 같습니다.
그래도 실행컨텍스트의 개념을 한 번 정리해두니 이제 흐름이 보이는 것 같습니다!
이번엔 머릿속에 조금 더 오래 남을 것 같아요..ㅎ
https://www.youtube.com/watch?v=EWfujNzSUmw
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures