[LearningJS] 스코프(Scope)

Scope (== Visibility)

  • 변수와 상수, 매개변수가 언제 어디서 정의되는지 결정(계층구조)
  1. 존재

    • 변수(let)와 상수(const)는 만들기 전에는 스코프 안에 존재하지 않는다.
    • 스코프는 프로그램의 현재 실행중인 부분(실행 컨텍스트)에서 현재 보이고, 접근할 수 있는 식별자를 말한다.
    • 존재한다는 것은 ‘그 식별자가 메모리가 할당된(or 예약된) 무언가를 가리키고 있다’.
  2. 정적 스코프와 동적 스코프

    • 정적 스코프 : 어떤 변수가 함수 스코프 안에 있는지 **함수를 정의할 때** 알 수 있다.
      • 정적 스코프는 전역 스코프, 블록 스코프, 함수 스코프에 적용된다.
  3. 전역 스코프 : 프로그램이 시작될 때 암시적으로 주어지는 스코프

    • 전역 스코프에서 선언한 것은 무엇이든 프로그램의 모든 스코프에서 볼 수 있다.
    • 전역 스코프에 변수, 함수 등이 몇 가지 존재하는 건 피할 수 없고, 나쁜 것이 아니다.
      • 다만 전역 스코프에 의존하는 것은 매우 나쁜 것이고, 피해야 한다.
      • ex) 사용자 정보 등의 변수는 객체 내부에 프로퍼티로 보관하는 것이 낫다.
  4. 블록 스코프 : 그 블록의 스코프에서만 보이는 식별자를 의미한다.

    • let, const는 식별자를 블록 스코프에서 선언한다.
  5. 변수 숨기기 : 내부에서 변수 x를 같은 식별자로 내부 블록에서 정의함으로써 외부의 변수 x를 가린다. (두 변수 x는 이름만 같고 다른 변수이다.)

    • 스코프 체인 : 어떤 변수가 스코프에 있는지 확인하는 개념. 현재 스코프 체인에 있는 모든 변수는 스코프에 있는 것이며, 숨겨지지 않았다면 접근할 수 있다.
  6. 클로저(Closure) : 함수가 특정 스코프에 접근할 수 있도록 의도적으로 그 스코프에서 정의하는 경우(스코프를 함수 주변으로 좁히는 것)

    • 클로저 안에 블록 스코프의 객체를 담아 리턴하면, 스코프 바깥에서 클로저에 접근해서 내부 블록의 객체에 접근할 수 있다.
    • 함수를 정의해 클로저를 만들면 해당 스코프가 더 오래 유지되고, 접근할 수 없던 것들에 접근할 방법이 생긴다.
  7. 즉시 호출하는 함수 표현식(IIFE) : 함수를 선언하고 즉시 실행한다.

    (function() {
        // IIFE 바디
    })();
    
    • 장점 : 내부에 있는 것들이 모두 자신만의 스코프를 가지지만, IIFE 자체는 함수이므로 그 스코프 밖으로 무언가를 내보낼 수 있다.
    • IIFE 내부에서 선언된 변수는 IIFE의 스코프 안에서 보호되며 외부에서 접근할 수 없다.
    • 클로저를 만들고 클로저에서 무언가를 반환받을 때 유용하게 사용할 수 있다.
  8. 호이스팅(Hoisting) : 끌어올린다. (변수 var 혹은 함수 선언)

    • let 변수는 그 변수를 선언하기 전에는 존재하지 않는다. 하지만 var 변수는 선언하기 전에도 존재하며 사용가능하다.
      • let 변수는 선언되지 않은 변수를 사용하면 에러 발생, var 변수는 호이스팅에 의해 선언되지 않은 변수를 사용해도 undefined 상태로 존재한다.
      • 변수를 선언하기도 전에 사용하면 불필요하게 혼란스럽고, 에러에도 취약하다.
    • 호이스팅은 var로 선언한 변수를 스코프의 맨 위로 끌어올리는데, 변수의 선언(var x;)만 끌어올려지고, 할당(x = 3;)은 끌어올려지지 않는다.
    • var를 이용해 변수를 선언하면 같은 변수를 여러번 정의하더라도 무시한다.
      • let은 같은 변수를 여러번 정의할 수 없다.
    • 함수 호이스팅을 통해 함수를 선언하기 전에 호출할 수 있다. 하지만 변수에 할당한 함수 표현식은 끌어올려지지 않는다. let f = function() {}
  9. 스트릭트 모드 : 암시적 전역 변수를 허용하지 않는다. ('use strict';)

    • 전역 스코프에 스트릭트 모드를 적용하면 스크립트 전체의 동작 방식이 바뀌므로 주의해야 하며, 전역 스코프에서 스트릭트 모드를 사용하지 않는 것이 좋다.
    • 함수 하나하나 마다 스트릭트 모드를 붙이기는 귀찮기 때문에, 즉시 실행되는 함수 표현식(IIFE) 내부에 모든 코드를 작성해서 사용하면 된다. 이렇게 하면 표현식 내부의 코드는 스트릭트 모드로 작동하지만, 표현식 내부의 코드와 함께 동작하는 다른 스크립트는 스트릭트 모드의 영향을 받지 않는다.

태그:

업데이트:

댓글남기기