![]()
자바스크립트를 사용하는 사람으로써, 요즘 자바스크립트의 근본? 내부? 원리? 라고 표현해야할까? 그런 부분에 대한 공부를 해야 할 필요성을 느껴서, 다른 블로그들을 참고하면서 공부 한 내용을 내 벨로그에 기록하고싶어서 이렇게 포스팅을 남긴다!
스코프 체인이 무슨말일까? 이게 무슨 말인지 알려면 우선 자바스크립트에서 말하는 스코프가 무엇인지부터 알아야한다!
사전에서 나오는 스코프(Scope)의 의미는 "범위" 라는 뜻이다. 그렇다면 스코프(Scope)란 것은 자바스크립트에서 어떤 범위를 나타내는 말이라고 유추 할 수 있다!
스코프(Scope)는 변수의 유효범위를 표현하는 말이다.
그러면 체인(Chain)은 뭘까! 체인의 사전적인 의미는 "사슬", "연쇄" 이런 뜻이다.
그렇다면, 스코프체인은 범위는 범위인데 연쇄적인 범위? 이런 의미가 아닐까?
즉, 범위 안의 범위, 그 범위 안의 범위.. 이런느낌으로..

( 사슬인데 타원형의 사슬 대신 "범위" 라는게 주렁주렁 달려있는.. 이미지를 상상.. )
결론적으로, 자바스크립트에서 스코프 체인이라는 것은 다음의 의미이다.
자바스크립트 엔진은 식별자를 찾을 때 일단 자신이 속한 스코프에서 찾고 그 스코프에 식별자가 없으면 상위 스코프에서 다시 찾아 나간다. 이 현상을 스코프 체인 이라고 하며 스코프가 중첩되어있는 모든 상황에서 발생한다.
참조 : https://leehwarang.github.io/docs/tech/2019-10-07-scope.html
let a = 3; // 전역 변수
function outer() {
// outer 함수 실행 컨텍스트
let a = 1; // 지역 변수
function inner() {
// inner 함수 실행 컨텍스트
console.log(a);
}
inner();
}
// 전역 실행 컨텍스트 (GEC)
outer();
다음 코드가 있을때 결과를 예측해보자.
본능적으로 숫자 1 이 출력됨을 알 수 있다.
하지만! 포인트는 1의 출력이 아니다. 어떤 과정으로 1이 나오는가를 알아야한다.
outer() 함수가 실행되고 outer 안에 있는 inner() 함수가 실행되는데, 이 때 inner() 내부에서 변수 a를 탐색한다. 만약 내부에서 a를 찾지못하면 inner()를 감싸고있는 outer() 함수에서 변수 a를 탐색한다! 만약 a가 있으면 여기서 참조하고 여기도 a가 없다? 그러면 더 상위로 올라가서 탐색한다!
이게 자바스크립트에서 말하는 스코프체인 현상이다.
좀 더 자세히 알려면, 실행컨텍스트의 내부정보에 대해서 알아야한다.
실행 컨텍스트의 내부에는 다음과 같은 정보가 있다.
- VariableEnviroment
- LexicalEnviroment
- ThisBinding
이 중에서 VariableEnviroment 와 LexicalEnviroment 에는 현재 환경과 관련된 식별자 정보들이 담긴다.
VariableEnviroment 는 오직 식별자 정보를 수집하는 용도로 쓰이고, LexicalEnviroment 는 각 식별자에 담긴 데이터를 추적하는 용도로 쓰인다.
컨텍스트 내부 코드들을 실행하는 동안에 변수의 값들에 변화가 생기면 그 값이 LexicalEnviroment 에만 실시간으로 반영이 된다.
VariableEnviroment와 LexicalEnviroment의 차이는 값의 변화가 실시간으로 반영이 되느냐, 그렇지 않느냐의 차이만 있다.
여기서 스코프체인과 관련있는 정보는 LexicalEnviroment 이다.
‘어떤 실행 컨텍스트 A 에 대한 환경 정보가 담겨있는 사전’
LexicalEnviroment도 하위 정보들로 구성된다. 그 정보들은 다음과같다.
- enviromentRecord : 현재 컨텍스트 내부의 식별자 정보
- outerEnviromentReference : 외부 환경 참조
enviromentRecord는 현재 컨텍스트 내부의 식별자 정보들을 가지고 있는 부분이다.
즉 해당 컨텍스트에 선언된 변수, 함수등의 정보를 보관하고 있다.
outerEnviromentReference는 이름에서부터 알 수 있듯이 외부 환경에 대한 정보를 담고 있는 부분이고, 스코프체인 현상은 outerEnviromentReference에 의해서 만들어진다.
let a = 3;
function outer() {
// outer 함수 실행 컨텍스트
let a = 1; // 지역 변수
function inner() {
// inner 함수 실행 컨텍스트
console.log(a);
}
inner();
}
// 전역 실행 컨텍스트 (GEC)
outer();
전역 실행 컨텍스트
전역 실행컨텍스트는 outerEnviromentReference 정보가 없다. (제일 바깥이니깐)
1. 식별자 a와 outer 함수가 선언 되어있구나를 가장 먼저 인식하고 기록한다. (enviromentRecord)
2. 식별자 a 에 3을 할당한다.
3. outer() 함수를 실행한다.
outer 실행 컨텍스트
1. 식별자 a와 inner함수가 선언 되어있구나를 가장 먼저 인식하고 기록한다.(enviromentRecord)
2. 식별자 a에 1을 할당한다.
3. inner() 함수를 실행시킨다.
inner 실행 컨텍스트
1. console.log(a); 코드를 실행한다.
2. 근데 inner 실행컨텍스트 내부에는 식별자 a의 대한 정보가 없다.
3. outerEnviromentReference가 외부에서 a를 찾는다!
4. a의 대한 정보를 찾았으니 가져다가 쓴다!
여기서 주의할 점은 outerEnviromentReference는 가장 가까운 값을 찾으면 그걸로 끝이다.
이게 무슨 뜻이냐면, 위 코드를 보면 전역 컨텍스트에는 a가 선언되어있고, 숫자 3이 들어가있다.
그리고 inner를 감싸고 있는 outer에도 a가 선언되어있고 숫자 1이 들어가있다.
여기서 inner가 전역 컨텍스트에 있는 a값을 사용하지 않는다는 뜻이다.
만약 outer에도 a가 없으면, 그땐 전역 컨텍스트에 있는 a값을 사용한다!
이게 스코프체인 현상이 일어나는 과정이다.
인프런에 있는 정재남 강사님의 코어자바스크립트 강의를 많이 참고하여 쓴 글입니다.
https://www.inflearn.com/course/%ED%95%B5%EC%8B%AC%EA%B0%9C%EB%85%90-javascript-flow/dashboard