2차_2주차_방성준_회고록 - hyeone999/Docs-JS_deepDive_Study GitHub Wiki

2주차 회고록

실행 컨텍스트

소스코드의 평가와 실행

모든 소스코드는 실행에 앞서 평가 과정을 거치며 코드를 실행하기 위한 준비를 한다.
자바스크립트 엔진은 "소스코드 평가"와 "소스코드 실행" 2개의 과정으로 나누어 처리한다.
소스코드 평가 과정에서는 실행 컨텍스트를 생성하고 변수, 함수 등의 선언문만 먼저 실행하여 생성된 변수나 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프(렉시컬 환경의 환경 레코드)에 등록한다.
평가 과정이 끝나면 선언문을 제외한 소스코드가 순차적으로 실행되기 시작한다.
변수나 함수의 참조를 실행 컨텍스트가 관리하는 스코프에서 검색해서 취득한다. 그리고 변수 값의 변경 등 소스코드의 실행 결과는 다시 실행 컨텍스트가 관리하는 스코프에 등록된다.

실행 컨텍스트 스택

const x = 1;

function foo() {
    const y = 2;

    function bar() {
        const z = 3;
        console.log(x + y + z);
    }
    bar();
}

foo(); // 6
위 예제는 전역 코드와 함수 코드로 이루어져 있다.
자바스크립트 엔진은 실행 컨텍스트를 스택이라는 자료구조로 관리한다. 이를 실행 컨텍스트 스택이라고 한다.
실행 순서는 전역 코드의 평가와 실행 -> foo 함수 코드의 평가와 실행 -> bar 함수 코드의 평가와 실행 -> foo 함수 코드로 복귀 -> 전역 코드로 복귀 순서로 진행될 것이다.
실행 컨텍스트 스택은 코드의 실행 순서를 관리한다.

렉시컬 환경

실행 컨텍스트 스택이 코드의 실행 순서를 관리한다면 렉시컬 환경은 스코프와 식별자를 관리한다.
렉시컬 환경은 키와 값을 갖는 객체 형태의 스코프(전역, 함수, 블록 스코프)를 생성하여 식별자를 키로 등록하고 식별자에 바인딩된 값을 관리한다. 즉, 렉시컬 환경은 스코프를 구분하여 식별자를 등록하고 관리하는 저장소 역할을 하는 렉시컬 스코프의 실체다.

아래 코드의 실행 순서

var x = 1;
const y = 2;

function foo(a) {
    var x = 3;
    const y = 4;

    function bar (b) {
        const z = 5;
        console.log(a + b + x + y + z);
    }
    bar(10);
}

foo(20); // 42

1. 전역 코드 실행

2. foo 함수 코드 평가

3. foo 함수 코드 실행

4. bar 함수 코드 평가

5. bar 함수 코드 실행

6. bar 함수 코드 실행 종료

7. foo 함수 코드 실행 종료

8. 전역 코드 실행 종료


클로저

const x = 1;

function outerFunc() {
    const x = 10;

    function innerFunc() {
        console.log(x);
    }
    innerFunc();
}
outerFunc();
outerFunc 함수 내부에서 중첩 함수 innerFunc가 정의도고 호출되었다. 이때 중첩 함수 innerFunc의 상위 스코프는 외부 함수 outerFunc의 스코프이다. 따라서 중첩 함수 innerFunc 내부에서 자신을 포함하고 있는 외부 함수 outerFunc의 x 변수에 접근할 수 있다.

렉시컬 스코프

자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했느냐에 따라서 상위 스코프를 결정한다. 이를 렉시컬 스코프라고 한다.

클로저와 렉시컬 환경

const x = 1;

function outer() {
    const x = 10;
    const inner = function () { console.log(x); };
    return inner;
}

const innerFunc = outer();
innerFunc();
이처럼 외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저라고 부른다.

캡슐화와 정보 은닉

캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 말한다. 캡슐화는 객체의 특정 프로퍼티나 메서드를 감출 목적으로 사용하기도 하는데 이를 정보 은닉이라 한다.
function Person(name, age) {
    this.name = name;
    let _age = age;

    this.sayHi = function() {
        console.log(`Hi! My name is ${this.name}. I am ${_age}.`);
    };
}

const me = new Person('Lee', 20);
me.sayHi(); // Hi! My name is Lee. I am 20.
console.log(me.name); // Lee
console.log(me._age); // undefined

기술블로그

실행 컨텍스트
클로저