17장 생성자 함수에 의한 객체 생성
1. Object 생성자 함수
- 생성자 함수에 의해 생성된 객체를 인스턴스라 한다.
- js는 object 이외에도 String, Number, RegExp, Promise 등의 빌트인 생성자 함수를 제공한다.
- 객체를 생성하는 방법은 객체 리터럴이 더 편리하여 특별한 이유가 없으면 생성자 함수를 쓸 이유가 없다.
2. 생성자 함수
- 겍체 리터럴에 의한 객체 생성은 간단하지만 단 하나의 객체만을 생성한다는 단점이 있다.
- 만일 수십개의 객체를 선언해야 한다면 문제가 크다.
function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter());
console.log(circle2.getDiameter());
- 일반 함수와 동일한 방법으로 생성자 함수를 정의하고 new와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
생성자 함수의 인스턴스 생성 과정
- new 연산자와 함께 생성자 함수를 호출하면 js 엔진은 암묵적으로 인스턴스를 생성하고 개발자가 쓴 코드를 기반으로 인스턴스를 초기화 한 후 인스턴트를 반환한다.
-
인스턴스 생성과 this 바인딩 : new 연산자를 이용하여 생성자 함수를 호출하면 자바스크립트 엔진은 암묵적으로 인스턴스를 생성한다. 그 후 this와 인스턴스는 바인딩된다.(바인딩 : 식별자와 값을 연결하는 과정) 이 처리는 런타임 이전에 실행된다. (만일 바인딩 되지 않았다면 함수 내 this는 함수가 아닌 global을 가르킨다.)
-
초기화 : 생성자 함수에 기술되어 있는 코드가 한 줄씩 실행되어 this에 바인딩되어 있는 인스턴스를 초기화한다.
-
인스턴스 반환 : 초기화 단계가 끝나면 완성된 인스턴스가 암묵적으로 반환된다. 이때 명시적으로 반환된다면 암묵적 반환은 무시된다. 따라서 return 문은 반드시 생략한다.
[[Call]] 과 [[Construct]]
- 함수 객체도 일반 객체가 가지고 있는 내부 슬롯과 내부 메서드를 모두 가지면서 함수 객체만을 위한 내부 슬롯과 내부 메서드를 추가로 가지고 있다.
- 일반 객체는 호출할 수 없지만 함수객체는 호출할 수 있는 이유는 함수 객체는 내부 메서드인 [[Call]]을 가지고 있기 때문이다.
- 또한 new 연산자와 함께 생성자 함수로서 호출되면 내부 매서드인 [[Construct]] 가 호출된다.
- 모든 함수 객체는 [[Call]] 메서드를 가지고 있고 이들을 callable이라 한다.
- [[Construct]] 메서드를 가지지 않은 함수 객체도 있다.(축약표현 메서드와 화살표함수 등) 가진 함수객체를 constructor, 가지지 않은 함수 객체를 non-constructor 라고 부른다.
new 연산자
- new 연산자와 함께 함수를 호출하면 생성자 함수로 동작한다.
- new 가 붙어있으면 [[Construct]] 내부 메서드를 호출하는 것이고 아니면 [[Call]] 내부 메서드를 호출하는 것이다.
new.target
- constructor인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용되며 메타 프로퍼티라 불린다.
- 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리킨다.
- new 연산자 없이 함수가 호출되면 new.target은 undefined 이다.
function Circle(radius) {
if (!new.target) {
return new Circle(radius);
}
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}