Table of Contents
스코프
- 스코프는 식별자의 유효범위를 의미한다
- 자바스크립트 엔진이 식별자를 검색할 때 스코프 체인을 통해 식별자를 참조하고 있는 코드의 스코프에서 시작해 상위 스코프 방향으로 이동하며 선언된 식별자를 검색한다
- 상위 스코프에서 유효한 식별자는 하위 스코프에서도 자유롭게 참조할 수 있지만, 하위 스코프에서 유효한 식별자는 상위 스코프에서 참조할 수 없다
- 식별자중에서 변수는 정의할 수 있는 키워드 종류가
var
,let
,const
이렇게 세 가지가 있는데,var
로 정의된 변수는 함수 레벨 스코프를 가지고,let
,const
로 정의된 변수를 블록 레벨 스코프를 가진다
스코프 결정 방식
- 식별자가 선언된 위치에 의해 스코프가 결정된다
let x = 'global'; // 글로벌 스코프를 가진다
function foo() {
let x = 'local'; // 지역 스코프를 가진다
console.log(x); // x를 참조하고 있는 이 코드는 자기 자신의 스코프에서 먼저 x를 찾고, 없으면 점점 상위 스코프로 확장한다. 여기서는 자신의 스코프에 'local'이 있다
}
foo();
console.log(x); // x를 참조하고 있는 이 코드는 자기 자신의 스코프가 글로벌이다. 그래서 글로벌에 정의된 'global'을 참조한다
스코프 종류
- 스코프는 크게 글로벌 스코프와 지역 스코프가 있다
- 글로벌 스코프에서 정의된 변수는 어디서든 참조할 수 있다
- 지역 스코프는 자신 스코프와 하위 스코프에서만 참조할 수 있다
var
로 정의된 변수는 함수 안에서 정의되었을 때만 지역 스코프로 여겨지고, 그 외의 경우에는 글로벌 스코프로 여겨진다- ES6에서 부터 블록 레벨 스코프를 지원하기 위해
let
,const
라는 키워드를 만들었다 - 덕분에
if
문,for
문,while
문,try/catch
문에서let
,const
로 정의한 변수가 자신 스코프를 지역 스코프로 다룰 수 있게 되었다
스코프 체인
- 코드에서 식별자를 참조하게 되면, 자바스크립트 엔진이 해당 식별자의 값을 찾게된다
- 이 때 식별자의 찾는 순서는, 식별자를 참조한 코드의 자신 스코프에서 점점 상위 스코프, 마지막으로 없으면 글로벌 스코프까지 순차적으로 탐색하게 된다
- 이렇게 자신 스코프 -> 상위 스코프들 -> 글로벌 스코프 순으로 찾는 모습이 마치 체인처럼 보여 스코프 체인이라 한다
렉시컬 스코프
- 함수는 다른 식별자들과 다르게 정의된 곳의 코드와 참조(호출)된 곳의 코드의 스코프가 다를 수 있다
- 정의된 곳을 상위 스코프로 결정하는 방식을 렉시컬 스코프 또는 정적 스코프라 한다
- 참조된 곳을 상위 스코프로 결정하는 방식을 동적 스코프라 한다
- 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프 방식을 따른다
const x = 1;
function foo() {
const x = 10;
bar();
}
function bar() {
console.log(x);
}
foo();
// foo 함수의 경우 정의된 곳과 참조된 곳 모두 글로벌 스코프다
// bar 함수의 경우 정의된 곳은 글로벌 스코프, 참조된 곳은 foo 함수 스코프다
// 그래서 bar 함수 안에서 x를 찾기 위해 상위 스코프로 이동할 때,
// bar 함수가 정의된 글로벌 스코프가 상위 스코프다
// 그래서 글로벌 스코프에서 x를 찾는다 -> 1을 출력