실행 컨텍스트: 실행할 코드에 제공할 환경 정보들(변수객체, 스코프 체인, this가 생성됨)을 모아놓은 객체(Stack)
호이스팅(hoisting): 변수 정보 수집
자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행한다고 알고 있지만
실제로 끌어올리지 않으며, 편의상 끌어올린 것으로 간주한다.
호이스팅 대상에 따라 끌어올리는 것이 다르다.
함수 내부의 모든 코드 실행이 완료되면 실행 컨텍스트가 Call Stack에서 제거된다.
함수를 새롭게 정의할 때 쓰는 두가지 방식이 있다.
함수 선언문(function declaration) | 함수 표현식(function expression) | |
---|---|---|
function 정의 | O | O |
변수에 할당 여부 | X | O |
함수명 정의 유무 | 필수 | 없어도 무관(기명/익명 존재) |
예시 코드 | function a( ) { } | const b = function () { } const c = function d() { } |
호이스팅 적용 유무 | O | X |
👩🏫<면접 질문>👨🏫
자바스크립트에는 특이한 특징이 있는데 코드(함수)가 실행되기 전에
자바스크립트 엔진
이 먼저, 선언된 변수와 함수를 가져가서 메모리에 저장(기억)을 해두는 것입니다.
호이스팅은 스코프 내부 어디서든 선언된 변수들을 최상위로 끌어올려 최상단에 선언된 것처럼 행동하는 것을 말합니다.
(호이스팅은 스코프 단위로 일어납니다.)
var
로 선언한 모든 변수는 선언하기 전에 사용할 수 있습니다. 코드가 실제로 이동하지 않지만 최상위로 끌어 올려진 것처럼 동작합니다.
var name;
console.log(name); // undefined
name = 'Sally'; // 할당
console.log(name); // Sally
undefined
라고 출력되는 이유는 선언은 호이스팅⭕되지만 할당은 호이스팅❌되지 않기 때문입니다.
즉, name이라는 변수만 올려진 것이고 변수에 할당하려는 Sally라는 값은 그 자리에 있는 것입니다.
호이스팅 시, 변수의 선언과 초기화를 (undefined 으로)같이 실행시킨다.
값을 할당하는 것은 나중에 원래 코드가 위치한 곳(제자리)에 도달했을 때 할당한다.
자바스크립트는 모든 것을 허용해주는 포용력 甲;;
선언은 했지만 값을 할당을 나중에 해도 ok!
값을 할당하고 나중에 변수를 선언해도 ok!
전역변수와 지역변수 개념이 확실치 않음!
변수명을 중복으로 사용도 가능!
이제 그만!! 🚫STOP🚫
그만큼 많은 💢문제💥가 발생하기 때문에 var
대신 변수 선언할 수 있는 새로운 키워드 let
과 const
가 ES6부터 사용 가능하게된 것입니다.
console.log(name); // ReferenceError: Cannot access 'name' before initialization
let name = 'Sally';
사실 let
과 const
도 호이스팅되지만 특별한 개념을 만들어냈는데 TDZ(Temporal Dead Zone) 때문에 let
과 const
는 호이스팅되지 않는 것처럼 오해할 수 있습니다.
console.log(name); // 🐞TDZ 영역🕸 안에 있으므로 사용 불가
let name = 'Sally'; // 함수 선언 및 할당
console.log(name); // 사용 가능
TDZ에 영향을 받는 let
과 const
는 (name이 호이스팅된 것은 알고있어도) TDZ 안에 있는 변수는 선언, 할당하기 전에는 사용할 수 없습니다.
name 초기화문이 나올 때까지는 name에 얼만큼 접근했든 간에 name이 선언 및 할당된 라인 전까지는 name을 쓸 수 없습니다.
이로 인해 코드 예측이 가능하고, 잠재적인 버그를 줄일 수 있는 장점👍이 있습니다.
let age = 30; // (1)
function showAge() {
console.log(age); // TDZ, ReferenceError
let age = 20; // (2) hoisting
}
showAge();
(2)에서 두번째로 선언한 변수 age가 호이스팅이 일어나 ReferenceError가 발생합니다.
만약 호이스팅이 일어나지 않았다면 showAge 함수 바깥에 (1)의 변수에 할당된 값 30이 출력될 것입니다.
var : 함수 스코프
=> 함수 내에서 선언된 변수만 지역변수가 됩니다.
함수가 아닌 일반 블록 외부에서는 변수 사용이 가능합니다.
(오직 함수만 지역변수로 호이스팅되고, 함수 외에 for문, if문 등은 다 전역변수로 호이스팅 시킵니다.)
let, const : 블록 스코프
=> if문, for문, while문 등 모든 코드 블록 내부에서 선언한 변수가 지역변수가 되며 블록 내에서만 유효합니다.
실행 컨텍스트는 자바스크립트가 실행되기 위해서 필요한 정보들인 '변수, 스코프 체인, this 값' 을 하나로 묶은 객체를 말합니다.
세가지 유형
Global 실행 컨텍스트
기본적으로 자바스크립트 코드가 시작할 때 가지는 실행 컨텍스트
전역으로 자바스크립트가 실행될 때의 실행환경입니다.
자바스크립트는 싱글 스레드이기 때문에 Global 실행 컨텍스트은 무조건 한 개만 존재할 수 있습니다.
함수적 실행 컨텍스트
기본적으로 함수 단위로 생성되어집니다.
자바스크립트는 함수마다 스코프를 가지게 되는데 함수가 호출되고 실행될 때 실행되는 함수의 실행 컨텍스트라고 생각하시면 됩니다.
함수 내부의 this값, 함수가 필요로 하는 지역변수들을 포함합니다.
eval (잘 사용되지 않음)