실행컨텍스트(Execution Context)
- 실행할 코드에 제공할 환경 정보들을 모아놓은 객체.
- 실행컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅), 외부 환경 정보를 구성하는 등의 동작
◼ 스택과 큐
- 스택: 출입구가 하나뿐인 데이터 구조. 즉 먼저 들어간 데이터가 가장 나중에 나오는 구조
- 큐: 양쪽이 모두 열려있는 데이터 구조. 먼저 들어간 데이터가 먼저 나오는 구조
즉, 실행컨텍스트는
동일한 환경에 있는 코드들을 실행할때 필요한 환경정보를 모아 컨텍스트를 구성하고 이를 콜 스택에 쌓아올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는 코드들을 실행한다.
◼ 동작 순서
- 처음 자바스크립트 코드를 실행하면, 전역 컨텍스트가 콜 스택에 담기고 함수들이 담긴다. 하나의 함수가 실행되면 콜스택에서 사라지고, 가장 상단에 있던 중단되었던 컨텍스트가 실행이 된다.
즉, 하나의 실행 컨텍스트가 콜 스택의 맨 위에 쌓이는 순간 = 현재 실행할 코드에 관여하는 시점
- VariableEnvironment: 담기는 내용은 LexicalEnvironment와 같지만, 최초 실행시의 스냅샷을 유지. 즉 실행 컨텍스트를 생성할 때 여기에 먼저 정보를 담고, 복사하여 LexicalEnvironment를 만듬
- LexicalEnvironment : 자바스크립트 코드에서 변수나 함수 등의 식별자를 정의하는데 사용하는 객체로 Environment Record와 Outer Environment Reference를 프로퍼티로 갖는다.
- ThisBinding: 식별자가 바라봐야 할 대상 객체.
◼ EnvironmentRecord
현재 컨텍스트와 관련된 코드의 식별자 정보가 저장됨. 컨텍스트를 구성하는 함수에 지정된 매개변수 식별자, 선언한 함수가 있을 경우, 그 함수 자체, var로 선언된 변수의 식별자등이 식별자에 해당됨.
호이스팅
function a (x) { // 수집대상 1(매개변수)
console.log(x); //(1)
var x; //수집대상 2(변수 선언)
console.log(x); //(2)
var x = 2; //수집대상 3(변수 선언)
console.log(x); //(3)
};
a(1)
//호이스팅
function a() {
var x = 1; // 수집대상 1(매개변수)
console.log(x); //(1)
var x; //수집대상 2(변수 선언)
console.log(x); //(2)
var x = 2; //수집대상 3(변수 선언)
console.log(x); //(3)
};
//호이스팅 마친 상태
function a() {
var x; // 수집대상 1의 변수 선언 부분
var x; // 수집대상 2의 변수 선언 부분
var x; // 수집대상 3의 변수 선언 부분
x = 1; // 수집 대상 1의 할당 부분
console.log(x); //(1), 1 출력
console.log(x); //(2), 1 출력
x = 2; // 수집대상 3의 할당 부분
console.log(x); //(3), 2 출력
}
a(1);
변수는 선언부와 할당부를 나누어 선언부만 끌어올리고, 함수 선언은 함수 전체를 끌어올린다.
//원본코드
function a (){
console.log(b); // (1)
var b = "bbb"; // 수집 대상 1 (변수선언)
console.log(b); // (2)
function b () {} // 수집 대상 2 (함수선언)
console.log(b); //(3)
}
a();
//호이스팅 마친 상태
function a () {
var b; // 수집대상 1. 변수는 선언부만
function b(){} //수집대상 2. 함수 선언은 전체를
console.log(b); // (1)
b = "bbb"; // 변수 할당부는 제자리에
console.log(b); // (2)
console.log(b); // (3)
}
a();
// 호이스팅 - 함수 선언문을 표현식으로 바꿈
function a() {
var b;
var b = function b(){}; // 선언문 -> 표현식
console.log(b); //(1) b 함수
b = "bbb";
console.log(b); //(2) bbb 출력
console.log(b); //(3) bbbb 출력
}
a();
함수 선언문과 함수 표현식
- 함수 선언문은 function 정의부만 존재하고 별도의 할당 명령이 없음
- 함수 표현식은 정의한 function을 별도의 변수에 할당하는 것. 함수명을 정의하면 기명 함수 표현식,
그렇지 않은 것을 익명 함수 표현식이라고 함. 보통 익명 함수 표현식이 일반적
//함수 정의하는 세 가지 방식
// 함수 선언문. 함수명 a가 곧 변수명.
function a() {}
a(); //실행o
// 익명 함수 표현식. 변수명 b가 곧 함수명
var b = function () {}
b(); //실행o
// 기명 함수 표현식. 변수명은 c , 함수명은 d
// c 함수 내부에서 c() 호출이든 d() 호출이든 잘 됨. 밖에선 d() x
var c = function d () {}
c(); //실행o
d(); //실행x
함수 선언문과 함수 표현식의 호이스팅
console.log(sum(1,2));
console.log(multiply(3,4));
function sum (a,b) {
return a+b;
}
var multiply = function (a,b) {
return a*b;
}
//호이스팅 마친 상태
var sum = function sum(a,b){ //함수 선언문 전체 호이스팅
return a+b;
};
var multiply; // 함수 표현식은 선언부만 호이스팅
console.log(sum(1,2)); //3출력
console.log(multiply(3,4)); //multiply is not a function 에러메세지 출력
multiply = function(a,b) {
return a*b;
}
◼ 스코프, 스코프 체인
- 스코프: 식별자에 대한 유효범위
- 스코프 체인: 식별자의 유효범위를 안에서부터 바깥으로 차례대로 검색해 나가는 것.
식별자를 찾을 때, 일단 자신이 속한 스코프에서 찾고, 그 스코프에 식별자가 없으면 상위 스코프에서 다시 찾아 나감
* 내부 함수에서는 외부 함수의 변수에 접근 가능하지만, 외부 함수에서는 내부 함수의 변수에 접근할 수 없다.
모든 함수들은 전역객체에 접근 가능
var x = 1;
function a(){
console.log(x) // 현재 자신의 스코프에 x가 없지만, 상위 스코프인 전역에서 x를 찾음 = 1
}
console.log(x); //1 출력
a(); //1 출력
렉시컬 스코프
스코프는 함수를 호출할 때가 아니라 선언할 때 생긴다. 즉 위치에 따라서 상위 스코프가 결정됨. 정적 스코프라고도 불린다.
let x = "global";
function a(){
let x = "local";
b();
}
//선언당시 전역스코프에 있기 때문에 전역변수인 x를 참조하게 된다.
function b(){
console.log(x);
}
a(); //global 출력
b(); //global 출력
'개발공부 > 자바스크립트' 카테고리의 다른 글
[JavaScript] 스터디 4일차_ this (2) call, apply, bind (0) | 2021.06.20 |
---|---|
[JavaScript] 스터디 3일차_ this (1) (0) | 2021.06.20 |
[JavaScript] 스터디 1일차_ 데이터 타입 (0) | 2021.06.15 |
[JavaScript] 스파르타 자바스크립트 기초 인강(8강~끝) (0) | 2021.06.08 |
[JavaScript] 스파르타 자바스크립트 기초 인강(1~7강) (0) | 2021.06.07 |