인프런 커뮤니티 질문&답변

taylous님의 프로필 이미지
taylous

작성한 질문수

자바스크립트 중고급: 엔진 핵심

Lexical Environment Component 생성과정 질문 입니다.

해결된 질문

작성

·

421

1

안녕하세요.

강의 막바지에 코드를 하나 소개 해주시면서 스스로 점검하는 시간을 가져라고 하셨는데, 직접 노트에 과정들을 하나하나 적으면서 했지만 아직 모호한 부분이 있는거 같아 검증 및 조언을 받고자 질문을 올리게 되었습니다.

function book() {
 function get() {
   return point;
 }
 var point = 123;
 return get();
}
console.log(book());

위의 코드에서 나름대로 제가 단계를 나눠 JavaScript Engine이 어떻게 실행하는지 적어보았습니다.

  1. JavaScript Engine이 함수 선언문을 먼저 검색합니다.
  2. function 키워드를 만났고 book 이라는 이름(name)을 가진 함수의 Execution Context를 생성합니다.
  3. 그리고 [[Scope]]에 현재 book을 감싸고 있는 object가 없으니 global object(window)를 참조하게 합니다.
  4. Execution Context에 Lexical Environment Component, Variable Environment Component, ThisBindingComponent를 초기화 해줍니다. (LEC안에는 Environment Record, Outer Lexical Environment 등이 있습니다)
  5. 그리고 book()안의 함수 선언문을 찾고 function get() { ... } 역시 2번부터 4번처럼 진행합니다.
  6. 함수 선언문 초기화가 끝났다면 변수를 찾습니다. var point를 찾았고 book 이름을 가진 object의 LEC.ER에  point: undefined를 가지는 property를 추가 해줍니다.
  7. 이제 코드를 실행 합니다. var point = 123 라인을 실행하며, LEC.ER에 있는 point에도 값이 할당 됩니다.
  8. return get() 라인을 실행하기 위해 get 이라는 이름을 book의 LEC에서 찾고, value(Function Object)를 실행(?)합니다.
  9. get의 LEC.ER에는 point가 없기 때문에 OLR를 통해 book의 LEC를 참조합니다.
  10. point를 찾아 반환합니다.
  11. console에 123이 출력 됩니다.

여기서 궁금한 점은 아래와 같습니다.

  1. 위의 절차가 맞을까요?
  2. 제일 궁금한 점은 설명하실 때 console.log(book()); 에서 시작하셨는데, 위의 코드가 test.js 파일로 저장되어 있고 node를 이용하여 실행한다고 가정하겠습니다. 그러면 JavaScript Engine이 함수 선언문을 찾을 텐데 이 때 book의 Execution Context를 생성해야 하는거 아닌가요? 강의에서는 book이 호출(book()으로 실행되었을 때)되었을 때 EC를 초기화 한다고 말씀하셨던거 같아 조금 혼란이 옵니다.
  3. function book() { ... } 이 호출되었을 때 즉, book object가 생성(?) 되었을 때 [[Scope]]가 할당된다고 하셨는데 그러면 이 때 OLC(Outer Lexical Environment)도 같이 할당되는 건가요? 그리고 "book object가 생성된다." 라는 말이 정확한지 모르겠습니다. "book"이라는 name 가진 property의 "value"를 참조한다는 말이 더 정확한가요?
  4. Variable Environment Component는 LEC와 동일하게 초기화 하고 추후에 처음상태로 초기화할 때 해당 object로 refresh 한다고 정리하였습니다. 그러면 해당 object의 property들은 항상 초기값을 유지하고 있는건가요?

답변 주시면 정말 감사하겠습니다.

답변 3

1

김영보님의 프로필 이미지
김영보
지식공유자

맞습니다만, property에 뉘앙스 차이가 있습니다.
function boo() {...}을 만나면 book = Function 오브젝트 형태로 만듭니다. Function 오브젝트가 되어야 호출할 수 있기 때문입니다.  
book = {}에서 {}는 빌트인 Object 오브젝트입니다. 여기서는 book = Function 오브젝트 형태이며, book = { 이안에 작성되는 것이 property }입니다. 물론 Function 오브젝트도 {} 형태로 표기할 수 있으며 {} 안에 작성한 모든 것이 프로퍼티입니다.


1

김영보님의 프로필 이미지
김영보
지식공유자

정리를 잘 하셨습니다. 멋있습니다. 아래 작성된 것을 참조해주세요.

2. function 키워드를 만났고 book 이라는 이름(name)을 가진 함수의 Execution Context를 생성합니다.
==> Function 오브젝트를 생성합니다. Execution Context는 함수를 호출했을 때 생성합니다.
==> 3과 4 사이에서 boo() 함수를 호출합니다.

6. book 이름을 가진 object의
==> book 이름의 Execution Context의

return get() 라인을 실행하기 위해 get 이라는 이름을 book의 LEC에서 찾고, value(Function Object)를 실행(?)합니다.
==> 맞습니다. 물음표가 있어 작성했습니다. 이때는 value 실행보다는 value 호출이, 문맥이 부드럽습니다.  

----------------------------
아래의 질문에서

1. 위의 절차가 맞을까요? 
==> 위에 작성한 Function 오브젝트 생성과 Execution Context 생성을 정리하면 맞습니다.

2. JavaScript Engine이 함수 선언문을 찾을 텐데 이 때 book의 Execution Context를 생성해야 하는거 아닌가요?
==> function 키워드를 만나면 Function 오브젝트를 생성합니다. 그리고 [[Scope]]에 생성하는 Function 오브젝트가 속한 스코프를 설정합니다. Function 오브젝트를 생성하는 시점에 스코프가 결정되며, 이를 정적 스코프라고 합니다.
이것을 정리하면 2번 질문과 3번 질문이 해결될 것 같습니다.

4. Variable Environment Component를
==> Object Environment Component로 바꾸면 문맥이 정리될 것 같습니다.

문장(단어, 용어)을 조그만 다듬으면 완전한 모습이 됩니다. 정리가 안되는 것이 있으면 지금처럼 질문을 해주세요.

0

taylous님의 프로필 이미지
taylous
질문자

답변 감사합니다.

설명해주신 부분 잘 이해가 되었습니다. Function 오브젝트가 생성된다는 말씀은 book()이 호출되기전에 book = {} 이렇게 property가 만들어지는 상황이라는 말씀이시죠?

taylous님의 프로필 이미지
taylous

작성한 질문수

질문하기