[TIL / DAY 10] 실행 컨텍스트와 스코프, 호이스팅

miseullang·2024년 10월 25일
post-thumbnail

🆕 새롭게 알게 된 것

📍 실행 컨텍스트 및 스코프


실행 컨텍스트

자바스크립트 코드가 실행되는 독립적인 공간(환경)이다.

🔊/민혁님 학교에서 수업을 듣는다고 가정할 때, 면학 분위기를 실행 컨텍스트에 비유할 수 있다.

면학 분위기를 통해 공부하는 공간이라는 걸 알 수 있고, 공부할 의지를 가질 수도 있다.

이처럼 명확히 표현하기는 어렵지만 실행 흐름이 바뀌는 맥락이라고 생각하면 이해하기 쉽다.

실행 컨텍스트의 구성 요소

실행 컨텍스트는 아래와 같이 구성되어 있다.

  1. 변수 환경 : 현재 블럭 내에서 선언된 변수만 취급하는 곳 (var로 선언된 변수만 취급 가능)

⇒ 값을 그대로 가져오기 때문에 더 빠르다.

  1. 렉시컬 환경

    • 환경 레코드 (record) : (let, const 로 선언된 변수만 취급 가능)

    ⇒ 메모리를 참조해서 가져오는 방식이라 var 방식보다는 조금 더 느림

    • 외부 환경 레코드 참조 (outer)

하지만 강의에서는 환경 레코드 (record)외부 환경 레코드 참조 (outer)에 대해서 다뤘다.


전역 컨텍스트 !== 실행 컨텍스트

  1. 레코드

자바스크립트는 실행 컨텍스트를 스택에 저장하며, 실행시 호출해서 사용한다.

스택은 후입선출/LIFO(Last In First Out) 구조를 가진다.

모든 자바스크립트 코드는 실행될 때 최소 1개의 전역 실행 컨텍스트를 가지고 실행된다.

  1. 아우터

함수 선언문은 따로 할당으로 분류할 수 있는 부분이 없으므로, 함수에서만 실행되는 함수 전용 컨텍스트를 생성한다. 스택에서 차례로 컨텍스트를 실행한 후, 더이상 실행시킬 컨텍스트가 없을 때 컨텍스트를 제거한다.

아우터는 자신의 상위 컨텍스트의 연결 통로 역할을 한다.

찾는 함수가 없다면, outer에서 다른 스코프와 연결되어 있는 게 있는지 탐색한다. (이것을 스코프 체인이라고 한다)

아우터 객체는 위에서 아래 방향으로만 이동한다.



실행 컨텍스트의 생성과 실행

생성(평가) : 변수를 할당할 메모리 공간을 미리 확보하기 위해 내가 실행할 코드를 모두 흝어보고, 레코드에 선언부를 기록한다.

** 생성 단계에서 하는 일

  • 변수를 선언하고 초기화
  • this 키워드를 바인딩(연결)
  • 스코프의 범위를 결정

⇒ 컨텍스트가 이런 식으로 동작하기 때문에 호이스팅이 발생하는 것!!

var로 선언한 변수는 레코드에 저장할 때 undefined 로 초기화 하지만, let, const로 선언한 변수는 레코드에 저장할 때 undefined 로 초기화하지 않고, 존재만 알린다.

⇒ let, const 선언은 곧바로 레코드 영역에 저장되지 않고 일시적 사각지대(Temporal Dead Zone)에 저장되며, 해당 키워드로 선언된 변수가 유의미한 값을 가질 때 레코드 영역으로 들어간다.



[ 🧀 / add ] let, const 키워드의 호이스팅 및 TDZ

사실 이 부분에서 이해가 잘 안 됐다. 마침 오늘 RBF를 하는 날이어서,  🔊/민혁님 이 해당 개념에 대해 공부한 내용을 공유해 주셨다.

호이스팅

기존의 자바스크립트에는 변수 선언 키워드가 var 뿐이었는데, var 가 가지는 고질적인 문제점(함수 스코프를 가짐, 호이스팅 문제, 중복 선언 가능 등)이 많아서 const, let 이 새로 만들어졌다.

그러므로 var의 문제점 중 하나였던 호이스팅 문제를 개선(?)해서 만들어졌는데, 자바스크립트는 실행 전에 일괄적으로 평가를 실행하므로 호이스팅 자체를 막을 순 없었다. 그래서 const, let으로 선언된 변수, 함수는 호이스팅이 일어나긴 하지만, 선언문 이전에 접근하는 경우 자바스크립트 엔진에 의해 접근이 차단된다.

⇒ 이것이 바로 일시적 사각지대(TDZ / Temporal Dead Zone)

민혁님 설명 듣고 바로 이해됨…! 미쳤다 샤라웃 투 민혁

일시적 사각지대(TDZ / Temporal Dead Zone)

console.log(apple);
console.log(banana);
// const, let으로 선언된 변수, 함수는 선언문 이전에 접근하는 경우 자바스크립트 엔진이 차단함

[여기까지가 일시적 사각지대]
-------------------------------

const banana ="good";
let apple = "very good";

스코프

식별자를 참조할 수 있는 범위

실행 컨텍스트가 영향을 미치는 범위

실행 컨텍스트 안에서 실행되는 코드들의 유효한 범위

  1. 전역 스코프
  2. 지역 스코프




📍호이스팅


코드를 선언과 할당으로 분리하고, 선언부를 최상위로 끌어올리는 것을 말한다.

print(); // 이렇게 작성하더라도

// 함수 선언문
function print() {
	console.log("a");
};

print(); // 이렇게 평가한다

호이스팅 예시

  1. 변수가 선언되기도 전에 참조하여 출력하고 있지만 error가 발생하지 않음
console.log(num); //undefined
var num = 10;
  1. 같은 코드인데 let 키워드로 변수 생성시 참조 오류 발생
//Uncaught ReferenceError: num is not defined
console.log(num);
let num = 10;
  1. printName() 함수가 선언도 되기전에 호출하고 있으나 잘 호출됨
printName(); // 윤희
function printName(){
  console.log('윤희');
}
  1. 함수 선언식은 is not a function 오류
printName(); // printName is not a function
var printName = () => {
    console.log("윤희");
};
  1. let 키워드로 선언시 참조 오류
//Uncaught ReferenceError: printName is not defined
printName(); 
let printName = function(){
  console.log('윤희');
}

let, const 키워드는 호이스팅이 되지 않는다.

[🧀 / add] 함수 스코프와 블록 스코프

1. 함수 스코프 (Function Scope)

함수 스코프는 함수 내에서 선언된 변수가 해당 함수 내부에서만 유효하다는 개념이다.

var 키워드로 선언된 변수의 유효 범위를 나타내며, 함수 스코프의 변수는 함수 내에서만 접근할 수 있으며 함수 밖에서는 접근할 수 없다.

function example() {
    var x = 10; // 함수 스코프 변수
    console.log(x); // 10
}
console.log(x); // ReferenceError: x is not defined
  1. 블록 스코프 (Block Scope)

블록 스코프는 중괄호 {}로 둘러싸인 코드 블록 내에서 선언된 변수가 해당 블록 내부에서만 유효하다는 개념이다.

let과 const 키워드로 선언된 변수의 유효 범위를 나타낸다. (ES6부터 도입)

블록 스코프의 변수는 블록 내에서만 접근할 수 있고, 블록 밖에서는 접근할 수 없다.

if (true) {
    let y = 20; // 블록 스코프 변수
    console.log(y); // 20
}
console.log(y); // ReferenceError: y is not defined

요약 : 함수 스코프는 함수 내에서 변수의 유효 범위를 제한하고, 블록 스코프는 중괄호로 둘러싸인 블록 내에서 변수의 유효 범위를 제한



📍참고 강의


https://school.programmers.co.kr/app/courses/24672/curriculum/lessons/343258#part-74206




✅ 정리

지금까지는 호이스팅에 대해서만 어렴풋이 알고 있었는데, 이번에 개념에 대해서 한 번 더 정리하는 시간이 됐다.

실행 컨텍스트 개념은 컴퓨터 밑바닥의 비밀 에서 클로저를 다룰 때 살짝 발을 걸쳐본 정도였는데, 오늘 공부를 통해 제대로 개념을 다진 것 같다.

특히 일시적 사각지대 부분은 민혁님이 딱 잡아주셔서 명쾌하게 이해할 수 있었다. 😉

profile
괴발개발 💻

0개의 댓글