# scope

참조 대상 식별자(변수)를 찾아내기 위한 규칙

  • 식별자는 자신을 참조할 수 있는 범위 (렉시컬 환경)를 갖는다.

  • 스코프는 식별자 이름의 충돌을 방지

  • 어떠한 변수가 스코프 안에 선언됐을때, 해당 스코프 안에서는 변수에 접근해서 읽거나 쓸 수 있고, 스코프 밖에서는 해당 변수에 접근할 수 없다.

# 스코프의 구분

전역 스코프 코드 어디에서든 참조 가능

지역 스코프(Local Scope/Function-level Scope) 함수 코드 블록이 만든 스코프

  • 변수 관점

전역 변수 전역에서 선언된 변수, 어디든 참조 가능

지역 변수 지역(함수) 내에서 선언된 변수, 지역의 하부 지역에서만 참조 가능

# 전역 스코프

  • var 키워드로 선언한 전역변수브라우저에서 전역객체 window의 프로퍼티이다.
  • 자바스크립트는 타 언어와 달리, 특별한 시작점(Entry Point)가 없어서 전역에 변수나 함수를 선언하기 쉽다.
    • c 언어의 경우 main 이 함수의 시작점
  • 전역 변수의 사용은 변수이름의 중복이 될 수 있다.
    • 의도치 않은 재할당에 의해 코드를 예측하기 어렵게 만든다.

# 블록 레벨 스코프 (block-level scope)

if, while, for { ... }

# Switch 안에서의 let과 const🔗

case 문은 별도의 Lexical Scope가 없다. (Uncaught SyntaxError: Identifier 'foo' has already been declared)

switch (foo) {
  case 1:
    let foo = 1;
    break;
  case 2:
    const foo = 2;
    break;
  /* ... */
}
1
2
3
4
5
6
7
8
9

블록 스코프가 필요한 곳의 case 문을 {} 로 감싼다.

  case 1: {
    let foo = 1;
    break;
  }
1
2
3
4

# 함수 레벨 스코프 (Function-level scope)

  • function() {...}

# 렉시컬 스코프

함수호출위치가 아닌, 함수 선언 위치에 따라 결정된다.

# 암묵적 전역(implicit global)

ES6 아래의, 엄격모드가 아닐때,

변수를 선언 없이 사용했을 경우, y = 20

  • JS 엔진은 window.y = 20 으로 해석하여 프로퍼티를 생성
  • 변수가 아니므로 호이스팅이 발생하지 않는다.

# 즉시실행 함수를 이용한 전역 변수 사용 억제 (IIFE)

  • 즉시 실행되고 전역에서 바로 사라진다.

# 스코프체인

식별자를 찾는 일련의 과정

변수가 스코프 안에 선언되지 않았다면, 그 변수를 찾기 위해 부모 스코프로 올라가고, 거기에도 없다면 또 그 부모 스코프에 올라가서 찾는다.

  • 코드에서 변수에 접근할 땐, 먼저 렉시컬 환경을 검색 범위로 잡는다.
  • 내부 렉시컬 환경에서 원하는 변수를 찾기 못하면 검색 범위를 내부 렉시컬 환경이 참조하는 외부 렉시컬 환경으로 확장한다.
  • 전역 렉시컬 환경으로 확장될 때까지 반복된다.

# 전역렉시컬에서 변수를 프로퍼티를 찾지 못했을 때,

  • 엄격모드 : 에러 발생
  • 비엄격모드 : 새로운 변수가 만들어 진다.
    • 하위호환성을 위해 남아있는 기능