코딩/JS

JS - Scope

최만규 2025. 6. 16. 19:27
728x90

 

1. 학습 목표

JS에서의 스코프의 개념을 이해하고, 여러 스코프 종류간의 차이를 알아보자.

 

스코프는 렉시컬 환경, 실행 컨텍스트, 클로저와 같은 JS 주요 개념들을 이해하는데 큰 도움이 된다.

 

2. 핵심 개념 요약

 

스코프(scope)

 

스코프란 식별자(변수, 함수, 클래스 이름 등)가 유효한 범위를 의미합니다. 

즉, 변수는 자신이 선언된 위치에 따라 다른 코드가 자신을 참조할 수 있는 범위가 결정된다.

 

렉시컬 스코프

위에서 언급한 것처럼 코드를 작성한 위치에 따라 스코프가 정해지는 규칙을 의미한다.

 

JS는 렉시컬 스코프 기반이며, 함수,변수가 어디서 정의 되었는지에 따라 상위 스코프가 결정된다.

 

스코프와 관련된 개념 중 렉시컬 환경과 실행 컨텍스트에 관해선 다음 글에서 다루겠다.

 

아무튼, 스코프를 잘 활용하면 식별자 충돌을 방지할 수 있고, 유지보수성과 가독성을 높일 수 있다.

 

 

3. 스코프 종류



전역 스코프

코드의 가장 바깥 영역에 선언된 변수 또는 함수가 속하는 스코프이다.

 

특징 : 어디서든 참조가 가능하고, 브라우저 환경에선 전역변수가 window객체의 속성이 된다.

 

그렇기에 전역변수를 남용하면, 네임스페이스 오염과 예기치 않은 버그가 발생할 수 있기에 조심해서 사용해야한다.

 

let globalVar = "I am global!";

function showGlobal() {
  console.log(globalVar); // "I am global!"
}

showGlobal();
console.log(globalVar); // "I am global!"

 

전역에서 선언한 변수인 globalVar을 함수를 호출해 함수 내부에서 참조하나, 같은 위치선상에서 호출해도 모두 접근이 가능하다.

 

지역 스코프

함수 몸체 내부에 선언된 변수 또는 함수는 지역 스코프에 속한다.

 

특징 : 자신의 지역 스코프와 하위 스코프에서만 유효하다. 함수가 실행될 때 생성되고 함수가 종료되면 소멸한다.

 

같은 이름의 변수를 여러 함수에서 사용해도 각각 독립적으로 동작하기에 의도치 않게 작동하지 않도록 주의한다.

 

function localScopeExample() {
  let localVar = "I am local!";
  console.log(localVar); // "I am local!"
}

localScopeExample();
console.log(localVar); // ReferenceError: localVar is not defined

 

localScopeExample 함수 호출 시, 함수 내부 선언한 변수를 참조하기에 정상적으로 I am local!이 출력되는데 반해,

콘솔문으로 localVar을 출력시 함수 내부 스코프에 접근하지 못하기에 참조 에러가 발생한다.

 

블록 스코프

ES6에서 도입된 let,const 키워드로 선언된 변수는 블록 내에서만 유효하다.

 

자바스크립트에서 {}로 감싸진 코드 영역을 의미한다. 즉, if, for, while과 같은 조건문/반복문 내에서만 유효한 스코프를 의미한다.

 

var는 위에서 언급한 let,const와 다르게 블록 스코프를 지원하지않는다.

 

if (true) {
  let blockVar = "I am block scoped!";
  console.log(blockVar); // "I am block scoped!"
}
console.log(blockVar); // ReferenceError: blockVar is not defined

 

if문 내부에서 선언된 blockVar의 경우 if문 블록 내부에서만 참조가 가능하다.

 

따라서, if문 바깥(스코프 외부 영역)에서 참조시 참조에러가 발생한다.

 

함수 스코프

var 키워드로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정한다.

 

특징으로, 위에서 언급한 블록의 경우 var는 지역 스코프가 생성되지 않으므로 의도치 않은 중복 선언이 발생할 수 있기에 주의할 필요가 있다.

 

function foo() {
  var x = "local";
  if (true) {
    var x = "still local!"; // 같은 스코프 내에서 중복 선언!
    console.log(x); // "still local!"
  }
  console.log(x); // "still local!"
}

 

블록 내부에서 선언한 x는 이전에 선언한 x를 재선언 및 재할당하게되며 'still local'이라는 문자열을 저장한다.

 

따라서, 블록 내부 및, 외부에서 모두 still local이라는 문자열 값을 출력하게된다.

 

 

4. 스코프 체인과 변수 검색

 

스코프는 계층적으로 연결될 수 있다.

 

함수가 중첩되면 중첩 함수의 지역스코프는 외부 함수의 지역 스코프와 계층적 구조를 가진다.

 

이렇게 체이닝이 얽히며, 결국 모든 지역 스코프의 최상위에는 전역 스코프가 존재한다.

 

변수 참조 시, JS엔진은 변수가 선언된 위치를 찾기 위해 스코프 체인을 따라 상위 스코프로 이동하며 검색한다.

 

또한 하위 스코프에서 상위 스코프는 참조할 수 있지만, 반대로 상위 스코프에서 하위 스코프의 변수는 참조가 불가하다.

 

복습(렉시컬 스코프)

let x = "global";
function foo() {
  console.log(x);
}
function bar() {
  let x = "local";
  foo();
}
bar(); // "global"

 

아까 언급한 (렉시컬 스코프)정적 스코프에 따라서 js에선 함수의 상위 스코프는 함수가 정의된 위치에 따라 결정된다.

함수 호출의 위치와는 무관하다는 뜻이다.

 

위 코드를 보면, 최상위에서 global이라는 문자열 값이 저장된 let 키워드로 선언된 x가 존재한다.

 

bar 함수에선 x가 선언되지만 블록스코프를 따르기에, x는 해당 함수 내부 지역스코프를 가진다.

 

bar내부에서 호출되는 foo함수는 선언된 곳 기준으로 스코프를 기억한다.

 

참조가능한 x는 foo함수 내부 혹은 전역 상태이기에 상위에서 상위에서 선언된 'global' 문자열 값을 가진 x에 대해서 출력하게 된다.

 

6. 참고 자료

다음 글에선 오늘 내용을 이어서 렉시컬 환경, 실행컨텍스트 그리고 클로저에 대해서 알아보자

https://m.yes24.com/goods/detail/92742567

 

모던 자바스크립트 Deep Dive - 예스24

『모던 자바스크립트 Deep Dive』에서는 자바스크립트를 둘러싼 기본 개념을 정확하고 구체적으로 설명하고, 자바스크립트 코드의 동작 원리를 집요하게 파헤친다. 따라서 여러분이 작성한 코드

m.yes24.com

 

해당 글을 참고해 필사한 글입니다.

728x90