[JavaScript] 스코프(Scope)

2026. 3. 9. 18:57·프론트엔드/Language

스코프(Scope)

Scope란?

식별자(변수, 함수, 클래스 등)가 유효한 범위를 말한다.

어떤 변수가 어디에서 선언되었는지에 따라 그 변수에 접근할 수 있는 영역이 결정된다.

 

스코프를 한마디로 정의하면 

"변수가 어디까지 살아있고, 어디서부터 죽느냐"

를 결정하는 규칙이다.

 

 

본격적으로 들어가기전에 변수 호이스팅과 TDZ에 대한 간략한 설명을 먼저 하겠다.

 

호이스팅이란?

 

코드를 실행하기 전, 인터프리터가 변수와 함수 선언을 스코프의 맨 위로 끌어올리는 것처럼 동작하는 특성을 말한다.

실제로 코드가 위로 옮겨지는 것이 아니라, 메모리 공간을 미리 확보하는 과정이다.

 

1. 변수 종류별 차이점

변수 호이스팅 여부 초기화 단계 특징
`var` O `undefined`로 초기화 선언전 호출 시 `undefined` 반환
`let` O 초기화 X 선언 전 호출 시 `ReferenceError`발생
`const` O 초기화 X 선언 전 호출 시 `ReferenceError`발생

 

2. var의 호이스팅

var로 선언한 변수는 선언과 동시에 undefined로 초기화된다.

그래서 선언문 보다 위에서 변수를 참조해도 에러가 나지 않고 undefined가 출력됨.

 

3. let과 const의 호이스팅

`let` 과 `const`도 호이스팅은 일어난다.

하지만 `var`과 달리 초기화 단계가 선언문 위치에서 수행된다.

 

선언 전부터 선언 지점까지의 구간을 TDZ(Temporal Dead Zone, 일시적 사각지대) 라고 부른다.

이 영역에서 변수에 접근하려고 하면 자바스크립트는 Reference Error를 던진다.

 

4. 함수 호이스팅

  • 함수 선언문: 함수 전체가 호이스팅되어 어디서든 호출 가능
sayHello(); // "안녕하세요!"
function sayHello() { console.log("안녕하세요!"); }
  • 함수 표현식: 변수 호이스팅 규칙을 따른다.
sayHi(); // TypeError: sayHi is not a function (var인 경우)
var sayHi = function() { console.log("하이!"); };

 

따라서, 호이스팅 때문에 발생하는 혼란을 방지하기 위해 `var`보다는`let`과 `const`를 사용하는 것이 좋다.

그리고 변수는 가급적 사용하기 직전이나 스코프 상단에 선언하는 것이 좋다.

 

호이스팅과 TDZ를 알았으니 본격적으로 스코프에 대해 알아보자.

 

다음의 예시 코드를 함께 보자.

var x = 100;

function outer() {
    var y = 200;
    if (true) {
        console.log(y); 
    }
}
outer(); 
console.log(x);

 

1. 전역 스코프 (Global Scope)

코드의 가장 바깥 영역.

여기서 선언된 변수는 공공재와 같아서, 코드 어디에서든 접근하고 수정할 수 있다.

  • 특징: 프로그램이 시작될 때 만들어지고, 프로그램이 종료될 때까지 사라지지 않음.
  • 예시의 var a = 100 ;: 이건 전역 변수다.
    함수 안에서도, 밖에서도 a가 누군지 다 알고 있음.
  • 그래서 console.log(a)를 하면 200 출력.

 

2. 지역 스코프 (Local Scope)

특정 함수나 블록 내부를 말한다.

여기서 선언된 변수는 그 구역의 전용 아이템이다.

  • 특징: 함수가 실행될 때 태어났다가, 함수가 끝나면 메모리에서 사라져버림.
  • 예시의 var y = 200;: 이건 outer()라는 함수 안에서만 유효한 지역 변수다.
  • 그래서 outer(); 하면 outer 함수 내의 console.log(y)로 200이 출력된다.

 

 

var x = 100;

function outer() {
    var x = 200;
    if (true) {
        console.log(x); 
    }
}
outer(); //1번
console.log(x); //2번

 

위의 상황에서는 어떻게 출력이 될까?

 

1번은 outer() 함수 내에서의 지역변수 x를 출력한다.

따라서 1번 출력값은 200이 된다.

 

2번은 전역 변수 x의 값을 출력한다.

따라서 2번 출력값은 100이된다.

 

더 자세히 설명하자면 다음과 같다.

 

1. 중첩된 스코프

지금 코드에는 총 3개의 층(Layer)가 있다.

  • 1층 전역 스코프
  • 2층 함수 스코프(outer)
  • 3층 if 블록 스코프

 

2. 스코프 체인

자바스크립트 엔진은 변수를 찾을 때 가장 안쪽(현재 위치)에서 시작해서 바깥쪽으로 나가며 탐색한다.

이를 스코프 체인이라고 한다.

 

다시 위의 코드를 보자.

 

# 1번 출력시

1. 3층 (if 문 안) : 여기 x가 있나? -> 없음

2. 2층 (outer 함수 안) : 여기에 x가 있나? -> 있음 ! (var x = 200)

3. 찾았으니까 200 출력!

* 전역 변수인 x = 100도 존재하지만, 더 가까운 곳에 있는 지역 변수 x가 전역 변수를 가려버린다.

이를 변수 섀도잉(Variable Shadowing) 이라 한다

 

# 2번 출력시

이 명령은 지금 1층(전역 스코프)에서 실행되고 있다.

1. 1층(전역) : 전역 스코프 내에 x 가 있나? -> 있음 ! (var = 100)

2. 이때 2층 안에 있는 x = 200 은 함수가 종료되면서 이미 사라졌거나, 애초에 다른 층이라 읽을 수 없음.

3. 따라서 전역 변수인 100을 출력!

 

3. 렉시컬 스코프

var x = 1;

function foo() {
    var x = 10;
    bar();
}

function bar(){
    console.log(x);
}

foo();
bar();

 

위 예제의 실행 결과는 bar 함수의 상위 스코프가 무엇인지에 따라 결정된다.

1. 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정

2. 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정

 

첫 번째 방식으로 함수의 상위 스코프를 결정한다면 bar 함수의 상위 스코프는 foo 함수의 지역 스코프와 전역 스코프 일 것이다.

두 번째 방식으로 함수의 상위 스코프를 결정한다면 bar 함수의 상위 스코프는 전역 스코프일 것이다.

 

전자의 방식을 동적 스코프, 후자의 방식을 정적 스코프 혹은 렉시컬 스코프 라고 한다.

 

결론적으로 위의 bar 함수는 전역 스코프를 상위 스코프로 결정한다.

자바스크립트를 포함한 대다수의 프로그래밍 언어는 렉시컬 스코프를 따르기 때문이다.

 

마무리

이렇게 스코프에 대해 알아보았다.

스코프에 대해 공부하다보니

한 눈에 스코프 구역을 나눠서 볼 수 있도록 시각화해주는 장치가 있으면 좋을 것 같아서

제미나이 캔버스로 만들어보았다.

 

🔗 스코프 시뮬레이터

 

다음 포스팅에서는 실행 컨텍스트에 대해 깊이 파헤쳐 볼 생각이다.

'프론트엔드 > Language' 카테고리의 다른 글

[TypeScript] 제너릭, Type Predicate, 함수 오버로드, async/await  (0) 2026.03.31
[JavaScript] 실행컨텍스트 & 클로저  (0) 2026.03.19
'프론트엔드/Language' 카테고리의 다른 글
  • [TypeScript] 제너릭, Type Predicate, 함수 오버로드, async/await
  • [JavaScript] 실행컨텍스트 & 클로저
yun_cic
yun_cic
  • yun_cic
    체대생의 개발 기록
    yun_cic
  • 전체
    오늘
    어제
    • 분류 전체보기 (32)
      • 백엔드 (1)
      • 프로젝트 (6)
      • etc (5)
      • 대외활동 (1)
      • 강의자료 (5)
      • 프론트엔드 (5)
        • Language (3)
        • Library (0)
      • 우테코 (9)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
    • 포트폴리오 페이지
  • 공지사항

  • 인기 글

  • 태그

    Python
    bs4
    Crawling
    크몽
    fastapi
    fe
    백엔드
    메모
    채널톡
    MySQL
    해커톤
    우아한테크코스 8기
    우테코 8기
    외주
    KUCC
    크롤링
    개발자 #코딩 #체대생
    todo
    Selenium
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
yun_cic
[JavaScript] 스코프(Scope)
상단으로

티스토리툴바