2021. 7. 30. 21:59ㆍ개발공부/자바스크립트
스코프, 스코프 체인
스코프란?
- 식별자에 대한 유효범위
- 변수에 접근 할 수 있는 범위
global scope(=전역 스코프)
A의 외부에서 선언한 변수는 A의 외부뿐 아니라 A의 내부에서도 접근 가능
local scope(=지역 스코프)
A의 내부에서 선언한 변수는 오직 A의 내부에서만 접근 가능
예) 함수 스코프: 함수내에서 선연한 변수는 해당 함수 내에서만 접근 가능
Scope Chain(=스코프 체인)
안에서부터 바깥으로 차례로 검색해 나감
➡️ 지금까지 LE의 environmentRecord의 정보 수집 과정을 보았는데 드디어 LE 내부의 나머지 outerEnvironmentReference가 나온다.
- outerEnvironmentReference는 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조한다.(??)
무슨말일까?
A함수 내부에 B함수를 선언하고 다시 B함수 내부에 C함수를 선언한 경우, 함수 C의 outerEnvrionmentReference는 함수 B의 LexicalEnvrionment를 참조한다. 함수 B의 LexicalEnvironment에 있는 outerEnvironmentReference는 다시 함수 B가 선언되던 때(A)의 LexicalEnvironment를 참조한다.
✨ 이처럼 outerEnvironmentReference는 연결리스트 형태를 띤다. '선언 시점의 LexicalEnvrionment'를 계속 찾아 올라가면 마지막엔 전역 컨텍스트의 LexicalEnvrionment가 있을것이다. 또한 각 outerEnvrionment는 오직 자신이 선언된 시점의 LexicalEnvrionment만 참조하고 있으므로 가장 가까운 요소부터 차례대로 접근할 수 있고 다른 순서로 접근하는 것은 불가능하다.
➡️ 이런 구조적 특성 덕분에 여러 스코프에서 동일한 식별자를 선언한 경우에는 무조건 스코프 체인 상에서 가장 먼저 발견된 식발자에만 접근 가능하다.
// 전역컨텍스트의 environmentRecord에 {a, outer}식별자 저장
// 전역컨텍스트는 선언 시점이 없음(=전역의 outerEnvironmentReference에는 아무것도 담기지않는다)
var a = 1;
var outer = function() {
var inner = function () { // outer실행 컨텍스트의 environmentRecord에 { inner }식별자 저장
console.log(a); // 아직 a에 할당 된 값이 없음
var a = 3; // inner실행 컨텍스트의 environmentRecord에 {a} 식별자 저장, outerEnvironmentReference에는 inner함수가 선언될 당시의 LexicalEnvironment가 담김
};
inner(); // inner실행 컨텍스트 활성화, outer함수 내부에서 선언됐으니 outer함수의 LE [ outer, { inner } ] 참조복사
console.log(a);
};
outer(); // outer함수 호출(= outer실행 컨텍스트 활성화)
console.log(a);
✨ 전역 공간에서는 전역 스코프에서 생성된 변수에만 접근가능 -> outer함수 내부에서는 outer 및 전역 스코프에서 생성된 변수에 접근 가능 & inner 스코프 내부에서 생성된 변수에는 접근 불가 -> inner함수 내부에서는 inner, outer, 전역 스코프 모두에 접근 가능
음🤔 inner함수내부의 console.log(a)의 값은 undefined로 출력된다. 내부함수임에도 전역스코프에있는 a의 값을 반환하지 않는 이유가 inner함수내에서 a식별자가 호이스팅되어버려서라고.. 추측하고있는데.. (스터디원들에게 물어보았다니 다들 나와 동일하게 추측하였다.)
하지만 스코프 체인 상에 있는 변수라고 해서 항상 접근 가능 한 것은 아니다?!
위의 코드에서 a는 전역공간과 inner 함수 내부에서 선언되었는데 inner함수 내부에서 a에 접근하려고 하면 무조건 스코프 체인 상의 첫번째 인자, 즉 inner 스코프의 LE부터 검색할 수밖에 없다. inner 스코프의 LE에 a 식별자가 존재하기때문에 더이상 스코프 체인 검색을 진행하지 않고 inner LE상의 a를 반환한다. 이를 변수 은닉화라고 한다.
출처: 정재남, 『코어 자바스크립트』, 위키북스(2019), 2장 실행 컨텍스트
'개발공부 > 자바스크립트' 카테고리의 다른 글
[JS] 콜백 지옥과 비동기 제어 (0) | 2021.07.29 |
---|---|
[JS] 비동기, promise, async/await 정리 (0) | 2021.07.07 |
[코어 자바스크립트] 클로저① - 클로저의 의미 및 원리 이해 (0) | 2021.06.27 |
[코어 자바스크립트] 콜백 함수 (0) | 2021.06.27 |
[코어 자바스크립트] this② 함수의 메소드 call, apply, bind (0) | 2021.06.25 |