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)
스코프 체인에 의한 변수 검색
outer함수가 호출되면outer의 지역 스코프에서a를 탐색한다.- 선언된
a가outer지역 스코프에 없으므로 상위 스코프(전역 스코프)에서a를 찾는다. → 값1을 출력한다.
- 선언된
inner함수가 호출되면 변수a가 먼저 선언된다.(호이스팅)inner의 지역 스코프에서a를 탐색한다.a가 할당되기 전이므로undefined가 출력된다.a에 값3을 할당한다.
outer의 지역 스코프에서a를 탐색한다.- 선언된
a가outer지역 스코프에 없으므로 상위 스코프(전역 스코프)에서a를 찾는다. → 값1을 출력한다.
- 선언된
- 마지막
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 = 1function bar(b) {let a = 2console.log(a, b) // 2, 1}bar(a)}
bar 함수 내부에 변수 a가 있으므로 bar 외부에 있는 a를 검색하러 가지 않는다. 내부에 이미 a가 있으므로 찾는 즉시 검색을 중단한다. 이를 shadowing이라고 한다. 더 안쪽의 식별자가 더 바깥쪽의 식별자를 가리는 것.
gatsby에서도 비슷한 느낌으로 shadowing이란 표현을 사용하는데... 다른 곳에서도 많이 나올 것 같다. 이 느낌을 기억해두자.
