Prototype [2] - new Func()의 엔진 동작

3631 단어 JavaScriptJavaScript

new Func()

new와 함께 호출된 함수를 생성자함수라고 합니다.
앞의 포스팅에서 생성자 함수가 객체를 반환한다고 했지만, 사실은 좀 다릅니다.
어떻게 다른지, 엔진 동작을 설명하면서 차근차근 설명하겠습니다.

1. Function Object의 [[construct]]

JS엔진이 실행 컨텍스트를 초기화하면서 Function Object를 만든다고 이전에 포스팅했습니다.
Function Object를 생성하면서 내부 프로퍼티 [[Scope]]에 함수 외부의 Scope를 참조하도록 설정하는데, 이와 마찬가지로 다른 내부 프로퍼티도 설정됩니다.

Function Object의 [[Construct]] 프로퍼티에 함수 그 자체를 참조하도록 설정해둡니다.
일반적인 함수 호출과는 다른 동작을 하기 위함입니다.

JS 엔진이 코드를 실행하다가 new 함수()라인에서 new를 만나면, 일반적인 함수 호출이 아니라
Function Object의 [[Construct]]를 호출합니다.(함수 원형 자체는 똑같음)

즉, 함수를 생성자로 호출하는 것인데,

호출 전에 엔진은 다른 일을 진행합니다. 바로 다음 목차를 봐주세요



2. new

new 연산자는 인스턴스 생성을 제어한다. new 또는 생성자자체가 인스턴스를 생성하는 것이 아닙니다.

function Person(name, age){
  this.name = name
  this.age = age
}

const cho = new Person();
  1. JS 엔진은 new 키워드를 만나면 빈 오브젝트를 생성합니다.
    이 오브젝트가 cho에 할당 될 객체입니다.
  2. JS 엔진은 이 빈 오브젝트의 내부 프로퍼티를 채워나갑니다.
    • 그 중, [[class]]에는 "Object"라는 값을 넣습니다.
      이것은 이 오브젝트는 JS Built-in Object 중, Object 타입임을 명시하는 것입니다.
    • [[prototype]] 에는 Person의 Prototype Object(우리가 흔히 말하는 Prototype)를 참조하도록 설정합니다.
      이것은 후에 인스턴스 객체의 __proto__에 담기게 됩니다. 이 설정으로 클래스 원형과 연결됩니다.
  3. 이제 Function Object의 [[Constructor]](생성자 함수)를 호출합니다.
    !!!여기서!!! 호출할 때, !!!생성자 함수의 this를 방금 만든 오브젝트로 binding하여 호출!!! 합니다.

호출된 생성자 함수의 역할

생성자 함수는 호출되면, 일반적인 함수 동작과 다를 바 없습니다.
그저 this로 바인딩 된 오브젝트의 프로퍼티를 변경하는 역할만 합니다.
어떠한 것도 return하지 않습니다.


반환은 new가

생성자 함수 실행이 완료되면, 해당 오브젝트는 채워질 것들이 다 채워졌습니다.
이제 다시 제어권이 new로 오고, new가 해당 오브젝트의 주소값을 반환합니다.


즉,

new 를 만난 "JS 엔진이" 빈 오브젝트를 생성하고
"생성자 함수가" 필요 정보를 채운 후
"new" 오브젝트의 주소를 반환합니다.



정리

JS Engine은 Function Object를 만들면서 [[construct]]에 자기 자신을 참조해두도록 만듭니다.
JS Engine이 new 함수이름()를 만나게 되면 다음과 같은 일련의 과정을 밟습니다.
1. 빈 오브젝트를 채우고, 그 오브젝트의 내부 프로퍼티를 채웁니다. [[class]], [[prototype]]
2. 내부 프로퍼티를 채웠으면, 함수이름으로 식별자해결을 진행합니다.
3. 식별자 해결을 통해 찾은 Funtion Object의 [[Construct]]가 참조하는 함수를 호출합니다.
이때 오브젝트를 this로 바인딩해서 호출합니다.
4. 생성자 함수는 개발자가 타이핑한 코드를 돌면서 this(엔진이 방금 생성한 오브젝트)의 프로퍼티를 변경합니다.
5. 생성자 함수 실행이 끝나면, new는 오브젝트의 주소를 반환합니다.

좋은 웹페이지 즐겨찾기