new
와 함께 호출된 함수를 생성자함수라고 합니다.
앞의 포스팅에서 생성자 함수가 객체를 반환한다고 했지만, 사실은 좀 다릅니다.
어떻게 다른지, 엔진 동작을 설명하면서 차근차근 설명하겠습니다.
JS엔진이 실행 컨텍스트를 초기화하면서 Function Object를 만든다고 이전에 포스팅했습니다.
Function Object를 생성하면서 내부 프로퍼티 [[Scope]]
에 함수 외부의 Scope를 참조하도록 설정하는데, 이와 마찬가지로 다른 내부 프로퍼티도 설정됩니다.
Function Object의 [[Construct]]
프로퍼티에 함수 그 자체를 참조하도록 설정해둡니다.
일반적인 함수 호출과는 다른 동작을 하기 위함입니다.
JS 엔진이 코드를 실행하다가 new 함수()
라인에서 new
를 만나면, 일반적인 함수 호출이 아니라
Function Object의 [[Construct]]
를 호출합니다.(함수 원형 자체는 똑같음)
new
연산자는 인스턴스 생성을 제어한다. new 또는 생성자자체가 인스턴스를 생성하는 것이 아닙니다.
function Person(name, age){
this.name = name
this.age = age
}
const cho = new Person();
new
키워드를 만나면 빈 오브젝트를 생성합니다.cho
에 할당 될 객체입니다.[[class]]
에는 "Object"라는 값을 넣습니다.[[prototype]]
에는 Person의 Prototype Object(우리가 흔히 말하는 Prototype)를 참조하도록 설정합니다.__proto__
에 담기게 됩니다. 이 설정으로 클래스 원형과 연결됩니다. [[Constructor]]
(생성자 함수)를 호출합니다.생성자 함수는 호출되면, 일반적인 함수 동작과 다를 바 없습니다.
그저 this로 바인딩 된 오브젝트의 프로퍼티를 변경하는 역할만 합니다.
어떠한 것도 return하지 않습니다.
생성자 함수 실행이 완료되면, 해당 오브젝트는 채워질 것들이 다 채워졌습니다.
이제 다시 제어권이 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는 오브젝트의 주소를 반환합니다.