스코프라는 단어를 직역해보면 범위, 영역이다.
그래서 JavaScript에서 스코프란 변수에 접근할 수 있는 유효한 범위
즉, 식별자에 대한 유효범위
라고 할 수 있다.
이때 식별자는 변수, 함수, 클래스의 이름을 뜻한다. 그래서 스코프란 변수, 함수, 클래스가 어디에서 선언됬는지에 따라서 유효범위가 결정된다고 할 수 있다.
{
const x = 1;
console.log('Block x: ', x); // Block x: 1
}
console.log('Global x: ', x); // ReferenceError: x is not defined
블록 외부에서는 블록 내부 안에있는 변수를 참조할 수 없다.
function add(a, b) {
const addValue = a + b;
}
console.log(addValue); // ReferenceError: addValue is not defined
console.log(a, b); // ReferenceError: a is not defined
함수 외부에서는 함수 내부에 있는 변수와 함수의 매개변수를 참조할 수 없다.
함수를 어디서 호출
했는지에 따라 상위 스코프가 결정된다.함수를 어디서 선언
했는지에 따라 상위 스코프가 결정된다.자바스크립트는 렉시컬 스코프를 따르므로 함수를 어디서 선언했는지에 따라 상위 스코프가 결정된다.
함수가 호출된 위치는 상위 스코프를 결정하는데에는 아무런 의미를 주지 않는다.
const x = 10;
function example1() {
const x = 1;
example2();
}
function example2() {
console.log(x);
}
example1(); // 10
example2(); // 10
위 예시의 example2 함수는 전역에 선언이 되어있어, 자신이 선언된 전역 스코프를 기억하게된다.
그리고 example2 함수가 호출되면 호출된 곳이 어디든 자신이 기억하고 있는 전역 스코프를 상위 스코프로 사용하게 되서 위에 코드는 전역 변수 x의 값을 두 번 출력하게 된다.
함수는 전역에서도 정의될 수 있고, 함수 내부에서도 정의가 가능하다. 그래서 함수 안에 새로운 함수를 정의한 함수를 중첩 함수
(nested function), 외부에 정의된 함수를 외부 함수
(outer function)이라고 한다.
이것을 먼저 작성한 이유는 함수는 중첩이 가능하기 때문에 그 함수들이 실행했을때 생성되는 지역 스코프들도 중첩이 가능하기 때문이다.
이는 스코프가 함수의 중첩으로 인해서 계층적 구조를 갖는것을 의미한다.
global: a
inner: c
outer: b
global: a
변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다. - 모던 자바스크립트 Deep Dive
참고 문서