JavaScript 강의

3-2 실행컨텍스트(스코프, 변수, 객체, 호이스팅)

kagan-draca 2024. 8. 14. 10:19

 

실행컨텍스트 : 실행할 코드에서 제공할 환경 정보들을 모아놓은 객체이다.

역할 )

1. 선언된 변수를 위로 끌어올린다 = 호이스팅

2. 외부 환경 정보를 구성한다.

3. this 값을 설정한다.

 

콜 스택

스택은 LIFO(= FILO)으로 마지막에 들어간게 먼저 나온다 (= 먼저 들어간게 마지막에 나온다)

큐는 FIFO(=LILO)으로 먼저 들어간게 먼저 나온다. (= 마지막에 들어간게 마지막에 나온다)

 

콜 스택은 실행할 코드에 제공할 환경 정보들을 모아 놓는 객체로 Stack 방식을 사용한다.

 

사용 이유 ) 코드의 실행 순서를 보장한다.

 

 

위와 같은 코드의 콜 스택을 알아보면

 

코드실행 → 전역(in) → 전역(중단) + outer(in) → outer(중단) + inner(in) → inner(out) + outer(재개) → outer(out) + 전역(재개) → 전역(out) → 코드종료

 

1. 전역(In) (a = 1) 2. 전역(중단) (함수 호출에 의해 전역 중단)
3. outer(In) 4. outer(중단) (Inner 함수 호출에 의해 outer 함수 중단)
5. inner(in) 6. Inner(out) (함수 내부 로직 모두 실행 완료된 이후)
7. outer(재개) (중단 됐던 내부 로직에서 실행) 8. outer(out) (내부 로직 모두 실행된 후)
9. 전역(재개) (중단 됐던 부분에서 실행) 10. 전역(out) (전역 로직 모두 실행 완료 후) + 코드 종료

 

실행컨텍스트 객체의 실체(= 담기는 정보)

 

1. Varuable Environment

- 현재 컨텍스트 내의 식별자 정보를 가진다.

ex) var a

-  외부 환경 정보를 가진다.

- 선언 시점(snapshot)을 가진다.

 

2. Lexical Environment

- Varuable Environment와 동일하지만, 변경 사항을 실시간으로 반영한다.

 

3. This Binding

- this 식별자가 바라봐야 할 객체

 

Varuable Environment , Lexical Environment의 개요

VE vs LE : 담기는 항목은 완벽하게 동일하지만, 스냅샷 유지 여부가 다르다

                               (recode와 outer)

 

VE : 스냅샷을 유지한다.

LE : 스냅샷을 유지하지 않는다.(실시간으로 변경사항을 반영한다.)

 

결국, 실행 컨텍스트를 생성할 때, VE에 정보를 먼저 담은 다음, 이를 그대로 복사해서 LE를 만들고

이후에는 주로 LE를 활용한다.

 

 

Lexical Environment에 Environment Rocord(=record)와 호이스팅

1. 식별자 정보들을 기록한다.

ex) function(매개변수들), function 자체, var선언된 변수명

 

2. 컨텍스트 내부를 처음부터 끝까지 순서대로 흝어가며 수집

                     (코드가 실행 되는건 아닙니다.)

 

호이스팅 : 변수 정보 수집 과정을 쉽게 설명한 '가상 개념'

 

역할 ) 식별자 정보를 맨 위로 끌어 올리는 역할

 

호이스팅
적용 전 매개변수 적용 적용 
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기

function a (x) {
    console.log(x);
    var x;
    console.log(x);
    var x = 2;
    console.log(x);
}
a(1);
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기

function a () {
    var x = 1;
    console.log(x);
    var x;
    console.log(x);
    var x = 2;
    console.log(x);
}
a(1);
//action point 1 : 매개변수 다시 쓰기(JS 엔진은 똑같이 이해한다)
//action point 2 : 결과 예상하기
//action point 3 : hoisting 적용해본 후 결과를 다시 예상해보기

function a () {
    var x;
    var x;
    var x;

    x = 1;
    console.log(x);
    console.log(x);
    x = 2;
    console.log(x);
}
a(1);
실행 결과 예측
1
undefined
2
1
undefined
2
1
1
2
실제 실행 결과
1
1
2
1
1
2
1
1
2

 

 

호이스팅
(함수는 무조건 호이스팅 된다고 가정)
적용 전 적용 후
//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기

function a () {
    console.log(b);
    var b = 'bbb';
    console.log(b);
    function b() { }
    console.log(b);
}
a();
//action point 1 : 결과 값 예상해보기
//action point 2 : hoisting 적용해본 후 결과를 다시 예상해보기

function a () {
    var b
    function b() {}
    console.log(b);
    b = 'bbb'
    console.log(b);
    console.log(b);
}
a();
실행 결과 예측
undefined
bbb
function b
function b
bbb
bbb
실제 실행 결과
function b
bbb
bbb
function b
bbb
bbb

 

호이스팅이라는 개념을 모르면 예측하기 어려운 결과

 

호이스팅 되는 함수

 

함수의 종류 :

함수 선언문 익명 함수 표기법
함수 선언문 전체가 호스팅 된다. 변수 부분만 호스팅 된다
ex) var b만 호스팅 된다
...

console.log(sum(3, 4));

// 함수 선언문으로 짠 코드
// 100번째 줄 : 시니어 개발자 코드(활용하는 곳 -> 200군데)
// hoisting에 의해 함수 전체가 위로 쭉!
function sum (x, y) {
    return x + y;
}

...
...

var a = sum(1, 2);

...

// 함수 선언문으로 짠 코드
// 5000번째 줄 : 신입이 개발자 코드(활용하는 곳 -> 10군데)
// hoisting에 의해 함수 전체가 위로 쭉!
function sum (x, y) {
    return x + ' + ' + y + ' = ' + (x + y);
}

...

var c = sum(1, 2);

console.log(c);
...

console.log(sum(3, 4));

// 함수 표현식으로 짠 코드
// 함수 선언부만 위로 쭉!
// 이 이후부터의 코드만 영향을 받아요!
var sum = function (x, y) {
    return x + y;
}

...
...

var a = sum(1, 2);

...

// 함수 표현식으로 짠 코드
// 함수 선언부만 위로 쭉!
// 이 이후부터의 코드만 영향을 받아요!
var sum = function (x, y) {
    return x + ' + ' + y + ' = ' + (x + y);
}

...

var c = sum(1, 2);

console.log(c);
함수 선언식으로 작성된 함수가 호스팅 돼
시니어 개발자가 sum 함수가 신입이 작성한 sum 함수로 바꿔
전체 코드에서 오류가 발생할 수 있다.
함수 표현식으로 작성된 함수라 변수 선언 부분만 호스팅 돼
시니어 개발자와 신입 개발자가 작성한
sum 함수가 순차적으로 실행된다.

 

Lexical Environment에 outerEnvironmentReference(=outer)와 스코프, 스코프 체인

outerEnvironmentReference (=outer) : 환경 정보를 담는다.

ex) 전역인가, 지역인가? 

 

1. 스코프

- 식별자의 유효범위

 

2. 스코프 체인

- outer는 현재 호출된 함수가 선언될 당시 환경 정보를 저장한다.

ex) A 함수 내에 B 함수 선언, B 함수 내에 C 함수 선언

 

결국 타고, 타고 올라가 전역 컨텍스트의 Lexical Environment를 참조하므로,

가장 가까운 요소부터 차례대로 접근한다.

 

호스팅 이전
호스팅 이후
따라서 출력 결과
undefined
1
1

 

실행 결과 예측 방법 : 

1. 콜백 Stack 만들기

2. 호스팅 작업하기

(변수 선언, 함수 선언문, 함수 표기법의 함수명 {} 범위 내에서 최상단에 올리기)

3. 콜백 Stack에 실행 순서 넣기

4. 변수 사용 시 콜백 Stack 내부에 변수 값이 있으면

가장 위에 있는 변수값 사용하기