JavaScript - 스코프(Scope)

치맨·2023년 1월 8일
1

javascript

목록 보기
4/23
post-thumbnail

목차

Scope란

  • Scope란 식별자(변수, 함수, 클래스 등)가 유효한 범위를 의미합니다.
  • 자바스크립트 엔진이 스코프를 통해 어떤 변수를 참조할지 결정하기 때문에, 식별자를 검색할 때 사용하는 규칙 이라고도 할 수 있습니다.
  • 범위는 중괄호 {} 또는 함수에 의해 나눠집니다.

Scope의 종류

  • Scope는 전역 스코프지역 스코프가 있으며, 함수레벨 스코프, 블록레벨 스코프로 나눌 수 있습니다.

전역 스코프

  • 코드의 가장 바깥 영역을 의미합니다.
  • 모든 스코프의 최상위 스코프는 전역 스코프입니다.
  • 전역 스코프에 선언한 변수를 전역변수 라고 합니다.

지역 스코프

  • 자바스크립트는 함수레벨 스코프를 따르므로 함수 몸체 내부를 지역 스코프라고 합니다.

  • 아래의 블럭레벨 스코프, 함수레벨 스코프 참고

  • 자신의 지역 스코프와, 하위 지역 스코프에서 유효합니다.

  • 상위 스코프에서 유효한 변수를 하위스코프에서 참조할 수 있지만, 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없습니다.

  • 지역 스코프에서 선언한 지역변수가 전역 스코프에서 선언한 전역변수보다 우선순위가 높습니다.

함수 레벨 스코프

  • var로 선언한 변수는 함수 레벨 스코프로서
    함수의 코드 블록만을 지역 스코프로 인정합니다.

  • 화살표 함수는 블록 레벨 스코프로 취급됩니다.

  • 따라서 var로 선언된 변수는 함수 안에서 선언하면 지역변수 이지만,
    코드블럭{} 내부에서 변수를 선언해도 모두 전역변수가 됩니다.

  • 아래의 사진에서 함수내부에 있는 scopeVal은 지역변수 이므로 참조할 수 없지만, 나머지 변수는 함수가 아닌 코드블럭{}에서 선언했으므로
    즉 전역변수 이므로 참조가 가능합니다.

블록 레벨 스코프

  • let, const로 선언한 변수는 모든 코드 블록(함수, if문, for문, while문, try/catch문 등)을 지역 스코프로 인정합니다.
  • 아래의 사진에서 global 변수를 제외한 모든 변수는 함수 및 코드블럭{} 안에서 선언 했기 때문에, 외부에서는 참조할 수 없습니다.

Scope의 필요성

  • 스코프가 없다면 같은 이름을 갖는 변수는 충돌을 일으키기 때문에 프로그램 전체에서 하나밖에 사용할 수 없다. 즉 효율적으로 메모리를 관리할 수 있다.

  • 예상치 못한 변수 수정을 방지할 수 있다.

Scope Chain

  • 스코프가 계층적으로 연결된 것을 스코프 체인(Scope Chain)이라고 한다.

  • 자바스크립트 엔진은 스코프 체인(Scope Chain)을 통해 현재 있는 스코프에서 상위 스코프방향으로 이동하며 선언된 변수를 검색한다.

  • 실행 컨텍스트의 렉시컬 환경을 단방향(현재=> 상위 스코프 => 전역 스코프)으로 연결한(chaining) 것이다.

동적스코프 vs 정적스코프

  • 동적 스코프

    • 함수가 호출되는 시점에 상위 스코프가 결정됩니다.
  • 정적 스코프

    • 정적 스코프 또는 렉시컬 스코프라고 부릅니다.
    • 함수가 정의되는 시점에 상위 스코프가 결정됩니다.
    • 자바스크립트를 포함하여 대부분의 언어가 정적스코프를 따릅니다.
  • 아래의 코드에서 정적스코프일때와 동적스코프일때 결과값이 다르게 나타납니다.

    • 정적스코프일 경우 : 선언이 된 기준이므로 hello KIM이 출력됩니다.
      이유는 call 함수가 선언된 시점에 name변수는 KIM을 참조하고 있기 때문입니다.

    • 동적스코프일 경우 : 호출된 시점에 상위 스코프가 결정되므로, call 함수가 호출된 시점에 name은 LEE를 참조하고 있기 때문에 hello LEE가 출력됩니다.

       var name = 'KIM';
      
       function scopeTest() {
         var name = 'LEE';
         call();
       }
      
       function call() {
         console.log(`hello ${name}`);
       }
      
       scopeTest();
      

Ref

profile
기본기가 탄탄한 개발자가 되자!

0개의 댓글