실행 컨텍스트란?
- 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
- 동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성 → 해당 실행 컨텍스트를 콜 스택에 저장 → 선입후출(stack)로 코드들을 실행하여 전체 코드의 환경과 순서 보장
- 예시
: 차례대로 전역 컨텍스트 push -> outer push -> inner push -> inner pop -> outer pop -> 전역 컨텍스트 pop/* 여기는 전역 컨텍스트입니다. */ var a = 1; function outer() { /* 여기는 outer 함수의 컨텍스트입니다. */ function inner() { /* 여기는 inner 함수의 컨텍스트입니다. */ console.log(a);// undefined 출력var a = 3; } inner(); console.log(a);// 1 출력 } outer(); console.log(a);// 1 출력
- 실행 컨텍스트에 포함되는 정보들은 다음과 같음
- VariableEnvironment
- 현재 컨텍스트의 식별자 정보 + 외부 환경 정보 (= 선언 시점의 LexicalEnvironment)
- 스냅샷 개념으로 변경 사항이 반영되지는 않음
- LexicalEnvironment(=정적 환경)
- 변경 사항이 실시간으로 반영되는 실행 환경
- ThisBinding
- this 식별자에 바인딩 되는 대상 객체
- VariableEnvironment
스코프(scope)란?
- 변수(식별자)에 대한 유효 범위
- 자바스크립트는 전역 공간을 제외하고 오직 함수에 의해서만 스코프가 생성됨
- 스코프 체인(scope chain)
- 스코프를 안에서부터 바깥으로 차례대로 검색해 나가는 것
- 변수 은닉화(variable shadowing) : 여러 스코프에서 동일한 식별자를 선언한 경우에는 무조건 스코프 체인 상에서 가장 먼저 발견된(가장 가까운) 식별자에만 접근 가능
/* 여기는 전역 컨텍스트입니다. */
var a = 1;
function outer() {
/* 여기는 outer 함수의 컨텍스트입니다. */
function inner() {
/* 여기는 inner 함수의 컨텍스트입니다. */
console.log(a);// undefined 출력var a = 3;
}
inner();
console.log(a);// 1 출력
}
outer();
console.log(a);// 1 출력
// → outer 함수에서는 outer 함수 스코프와 전역 스코프에 접근이 가능하지만, inner 스코프에는 접근이 불가능
// → inner 함수에서는 outer 함수 스코프와 전역 스코프에 모두 접근 가능
함수의 상위 스코프를 결정하는 방법
- 동적 스코프
- 함수가 어디서 호출되었는지에 따라 상위 스코프를 결정
- 정적 스코프(=렉시컬 스코프)
- 함수가 어디에 선언되었는지에 따라 상위 스코프를 결정
- 자바스크립트는 함수를 선언함으로써 스코프를 생성하므로 렉시컬 스코프에 따라 상위 스코프를 결정함
클로저란?
- 어떠한 함수를 렉시컬 스코프 밖에서 실행해도 원래 선언되었던 렉시컬 스코프를 기억하고 접근할 수 있도록 하는 특성
var color = 'red';
function foo() {
var color = 'blue'; // 2
function bar() {
console.log(color); // 1
}
return bar;
}
var baz = foo(); // 3
baz(); // 4
→ bar()는 자신이 생성된 렉시컬 스코프에서 벗어나 바깥 스코프에 위치한 baz라는 새로운 변수에 할당되어 실행이 됐는데도 정상적으로 작동이 되고 있음
→ 자바스크립트의 스코프(렉시컬 스코프)는 해당 코드가 작성된 문맥에서 바로 결정되기 때문에 GC에서 회수되지 않고 렉시컬 스코프를 유지할 수 있는 것임
- 대표적인 클로저 예시
function count() {
let i;
for (i = 1; i < 10; i += 1) {
setTimeout(function timer() {
console.log(i); // 9번의 10 출력
}, i*100);
}
}
count();
- 클로저 활용
- 함수 은닉화
'Language > Javascript' 카테고리의 다른 글
Javascript - script 로딩 시 async vs defer (0) | 2021.12.13 |
---|---|
Javascript - 애니메이션 구현 setInterval vs requestAnimationFrame (0) | 2021.12.12 |
Javascript - this (0) | 2021.11.28 |
Javascript - 부모 창에서 window.open()으로 연 자식 창 관리 (1) | 2021.10.03 |
Javascript - 고차함수 + 자주 쓰이는 ES6~ES12 문법 정리 (0) | 2021.07.24 |