본문으로 건너뛰기

Scope

스코프(Scope)는 변수와 함수의 접근 가능한 유효 범위를 나타내는 개념

Global Scope

  • 전역 스코프는 코드의 가장 바깥 영역에 해당하는 스코프
  • 전역 스코프에서 선언된 변수와 함수는 어디에서든 접근가능
  • 브라우저 환경에서는 window 객체, Node.js 환경에서는 global 객체가 전역 스코프를 나타낸다.
  • 전역 스코프에 선언된 변수와 함수는 계속 메모리에 상주하므로(제거 되지 않음), 과도한 사용은 메모리 낭비와 이름 충돌 문제를 야기할 수 있다.

Local Scope

지역 스코프는 함수나 블록 내부에서 선언된 변수와 함수의 유효 범위를 나타내는데, 함수 스코프(Function Scope)와 블록 스코프(Block Scope)로 구분된다.

스코프가 사라질 때 해당 스코프 내에서 선언된 변수와 함수가 메모리에서 해제되는데 이는 가비지 컬렉션(Garbage Collection) 메커니즘에 의해 처리된다.

Function Scope

  • 함수 내부에서 선언된 변수와 함수는 해당 함수 내에서만 접근할 수 있는 유효 범위를 가짐
  • 함수 외부에서는 함수 내부의 변수와 함수에 직접 접근할 수 없음
  • 함수 스코프는 함수와 var 키워드로 선언된 변수에 적용
  • 함수가 실행될 때마다 새로운 함수 스코프가 생성되며, 함수 실행이 완료되면 해당 스코프는 사라짐

Block Scope

  • 블록 스코프는 중괄호()로 둘러싸인 블록 내부에서 선언된 변수와 함수의 유효 범위를 가짐
  • 블록 내부에서 선언된 변수는 해당 블록 내에서만 유효하며, 블록 외부에서는 접근할 수 없음
  • 블록 스코프는 let과 const 키워드로 선언된 변수에 적용
  • 조건문, 반복문, 함수, try-catch...

그러므로 블록 스코프함수 스코프보다 변수의 유효 범위가 좁고 이는 다음과 같은 장점을 가진다.

  • 변수의 라이프사이클 명확화(사용 범위가 명확하게 구분)
  • 변수 이름 충돌 방지
  • 메모리 효율성 향상

Scope Chain

스코프 체인은 변수와 함수의 접근 순서를 결정하는 방식으로 자바스크립트 엔진은 변수나 함수를 찾을 때 현재 스코프에서 시작하여 상위 스코프로 차례로 이동하며 검색한다.

현재 스코프에서 변수나 함수를 찾지 못하면, 상위 스코프로 이동하여 검색하고 이를 반복한다.

전역 스코프까지 도달했는데도 변수나 함수를 찾지 못하면 ReferenceError가 발생한다.

Lexical Scope/Static Scope

자바스크립트는 렉시컬 스코프(정적 스코프)를 따르는데, 렉시컬 스코프란 함수의 상위 스코프는 함수를 선언할 때 결정되며, 함수가 어디에서 호출되는지는 영향을 받지 않는다는 것이다.

반대는 Dynamic Scope(동적 스코프)로 함수 호출시점에서 함수의 상위 스코프가 결정 된다는 개념이다.

Closure

JS에서는 Lexical Scope를 따르기 때문에 함수 선언 시점에서 내부 함수가 스코프 체인에 따라 외부 함수나 글로벌 스코프등에 접근 가능하다.

중첩된 함수에서 내부 함수가 외부 함수의 변수에 접근해 참조를 유지할 경우, 외부 함수의 실행이 종료되어 스코프가 사라진 후에도 내부 함수에서 해당 변수를 참조할 수 있는데 이를 클로져라고 한다.

function outerFunction(x) {
let y = 10;

function innerFunction() {
console.log(x + y);
}

return innerFunction;
}

const closure = outerFunction(5);
closure(); // 출력: 15

클로져는 외부에서 접근이 불가한 점 때문에, 다양하게 활용 된다.

  1. 모듈 패턴(Module Pattern): 모듈 패턴은 클로저를 사용하여 private 변수와 메서드를 캡슐화하고, public API를 노출하는 방식
  2. React의 useState Hook: 클로저를 활용하여 컴포넌트의 상태를 캡슐화하고, 상태 업데이트 함수를 제공

하지만 클로저를 남용하거나 잘못 사용하면 메모리 누수, 스코프 충돌, 성능 문제 등의 단점이 발생할 수 있으므로 주의가 필요하다.

  • 메모리 누수 위험: 외부 함수의 변수를 참조하는 내부 함수가 존재하는 한, 해당 변수는 메모리에서 해제되지 않음(메모리 누수가 발생 가능성)
  • 스코프 충돌 위험: 외부 함수의 변수와 내부 함수의 변수 이름이 충돌가능성
  • 성능 오버헤드: 클로저는 함수 실행 시 추가적인 메모리 할당과 스코프 체인 탐색이 필요하므로 성능 오버헤드가 발생할 수 있음

참조

created date: 2024-04-08 modified date: 2024-04-10