Skip to content
On this page

JavaScript 스코프 체인

수정하기
문서 생성 2021-05-15 16:13:22 최근 수정 2022-12-20 23:24:17

자바스크립트에서 함수는 중첩될 수 있으니 함수의 지역 스코프도 중첩될 수가 있다. 스코프가 함수의 중첩에 의해 계층적 구조를 갖는다.

var a = 1;
function outer() {
console.log(a);
function inner() {
console.log(a);
var a = 3;
}
inner();
console.log(a);
}
outer();
console.log(a);
  • outer 함수와 inner 함수의 지역이 있으며, inner 함수는 outer 함수의 중첩 함수이다.
    • outer 함수가 만든 지역 스코프는 inner 함수가 만든 지역 스코프의 상위 스코프이며, outer 함수의 지역 스코프의 상위 스코프는 전역 스코프이다. 이렇게 스코프가 계층적으로 연결된 것을 스코프 체인(scope chain)이라고 한다.
  • 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작해서 없으면 상위 스코프 방향으로 이동해서 계속 찾아나간다. (identifier resolution)

스코프 체인에 의한 변수 검색

  1. outer 함수가 호출되면 outer의 지역 스코프에서 a를 탐색한다.
    1. 선언된 aouter 지역 스코프에 없으므로 상위 스코프(전역 스코프)에서 a를 찾는다. → 값 1을 출력한다.
  2. inner 함수가 호출되면 변수 a가 먼저 선언된다.(호이스팅)
    1. inner의 지역 스코프에서 a를 탐색한다.
    2. a가 할당되기 전이므로 undefined가 출력된다.
    3. a에 값 3을 할당한다.
  3. outer의 지역 스코프에서 a를 탐색한다.
    1. 선언된 aouter 지역 스코프에 없으므로 상위 스코프(전역 스코프)에서 a를 찾는다. → 값 1을 출력한다.
  4. 마지막 a는 전역 스코프에서 탐색하고 값 1을 출력한다.

스코프 체인에 의한 함수 검색

// 전역 함수
function foo() {
console.log(`global function foo`);
}
function bar() {
// 중첩 함수
function foo() {
console.log(`local function foo`);
}
foo(); // 1
}
bar();
  • 1번에서 foo 함수를 호출하면 자바스크립트 엔진은 함수를 호출하기 위해 먼저 함수를 가리키는 식별자 foo(함수 선언문으로 정의하여 암묵적으로 함수 이름과 동일한 식별자가 선언된다.)를 검색한다.
  • 함수도 식별자에 할당되기 때문에 스코프를 갖는다. bar 내부 중첩 함수 foo가 실행되어 local function foo가 출력된다.

shadowing

function foo() {
let a = 1
function bar(b) {
let a = 2
console.log(a, b) // 2, 1
}
bar(a)
}

bar 함수 내부에 변수 a가 있으므로 bar 외부에 있는 a를 검색하러 가지 않는다. 내부에 이미 a가 있으므로 찾는 즉시 검색을 중단한다. 이를 shadowing이라고 한다. 더 안쪽의 식별자가 더 바깥쪽의 식별자를 가리는 것.

gatsby에서도 비슷한 느낌으로 shadowing이란 표현을 사용하는데... 다른 곳에서도 많이 나올 것 같다. 이 느낌을 기억해두자.

reference