13 스코프

13.1 스코프란?

[스코프] = 식별자의 유효범위

var, let, const 키워드의 스코프가 다르며, JS와 다른언어의 스코프도 차이가 존재

모든 식별자( 변수이름, 함수 이름, 클래스이름 등)은 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정된다. 이를 스코프 라고 한다.

스코프가 다르고 이름이 같은 두 변수가 있을 때, JS엔진은 이름이 같은 두 개의 변수중에 어떤 변수를 참조해야 할 것인지를 결정해야 하는데 이를 [식별자 결정]identifier resolution이라고 한다. 따라서 스코프는 JS엔진이 식별자를 검색할 때 사용하는 규칙 이라고 할 수 있다.

var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용된다. 이는 의도치 않은 변수값 재할당을 부르는 부작용이 있다.

function foo() {
  var x = 1;
  // var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용한다.
  // 아래 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작한다.
  var x = 2;
  console.log(x); // 2
}
foo();

하지만 let, const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않는다.

function bar() {
  let x = 1;
  // let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않는다.
  let x = 2; // SyntaxError: Identifier 'x' has already been declared
}
bar();

13.2 스코프의 종류

13.2.1 전역과 전역 스코프

전역: 코드의 가장 바깥 영역

전역은 전역 스코프를 만들며 이 전역 스코프는 어디서든지 참조할 수 있다.

13.2.2 지역과 지역 스코프

지역 : 함수 몸체 내부

지역변수자신의 지역 스코프와 하위 지역 스코프에서 유효하다.

전역과 각 지역 스코프 중에서 적합한 변수를 선택하는 것은 JS엔진이 스코프 체인을 통해 참조할 변수를 검색 Identifier Resolution 했기 때문이다.

  • 식별자 결정 = 변수를 검색 = Identifier Resolution

13.3 스코프 체인

함수는 중첩될 수 있다. => 중첩함수 nested function

함수가 중첩될 수 있으므로 함수의 변수들도 중첩될 수 있으며, 이는 스코프가 함수의 중첩에 의해 계층적 구조를 가질 수 있음을 의미함. => 스코프가 계층적으로 연결된 것 : [스코프 체인]

변수 참조시 JS엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.

  • [렉시컬 환경] Lexical Environment : 코드가 어디서 실행되며 주변에 어떤 코드가 있는지. 즉 코드의 문맥은 렉시컬 환경에서 이뤄진다.

상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만 하위 스코프에서 유효한 변수를 사우이 스코프에서 참조할 수 없다.

13.4 함수 레벨 스코프

c나 자바 등을 비롯한 대부분의 프로그래밍 언어는 함수 몸체뿐만이 아닌 모든 코드블록(if , for, while, try/catch 등)이 지역 스코프를 만든다. (= 블록 레벨 스코프) 하지만 var 키워드로 선언된 변수는 오로지 함수의 코드블록만을 지역 스코프로 인정한다. ( =함수 레벨 스코프)

ES6에서 도입된 let, const 키워드는 블록레벨 스코프를 지원한다. ch15.let, const 키워드와 블록레벨 스코프 에서 자세히 ...

13.5 렉시컬 스코프

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // ?
bar(); // ?
  • 함수를 어디에서 '호출'했는지에 따라 상위 스코프 결정 = 동적 스코프

  • 함수를 어디서 '정의'했는지에 따라 상위 스코프 결정 = 렉시컬 스코프, 정적 스코프

JS는 렉시컬 스코프를 따르기에 어디서 호출했는지가 아니라 어디에 정의했는지에 따라 상위 스코프를 결정한다. 호출위치는 무관함.

Last updated