17.1 Object 생성자 함수
new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하여 반환함
- 빈 객체를 생성한 후 프로퍼티 또는 메서드를 추가하여 객체 완성
const object = new Object();
object.name = 'Seo';
object.sayHi = function () {
console.log('Hi');
};
- 생성자 함수 : new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수
- JS에선 다양한 빌트인 생성자 함수 제공함
- Object 생성자 함수를 사용해서 객체를 생성하는 것은 그다지 유용하지 않음
17.2 생성자 함수
객체 리터럴에 의한 객체 생성 방식의 문제점
- 객체 리터럴에 의한 객체 생성 방식은 직관적이고 간편하지만, 생성시 한 개의 객체밖에 생성 못함
- 객체는 프로퍼티를 통해 객체 고유의 상태 표현, 메서드를 통해 객체의 동작 표현함
- 프로퍼티는 모두 다를 수 있지만, 메서드는 내용이 거의 동일함
- 동일한 프로퍼티 갖는 객체 여러개 생성시 비효율적
생성자 함수에 의한 객체 생성 방식의 장점
- 생성자 함수에 의한 객체 생성 방식은 객체 생성을 위한 템플릿처럼 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성 가능
- this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수
- this 바인딩은 함수 호출 방식에 따라 동적으로 결정됨
- 생성자 함수는 형식이 따로 정해져있는 것이 아니라 new 연산자와 함께 호출하면 생성자 함수로 동작
생성자 함수의 인스턴스 생성 과정
- 생성자 함수의 역할은 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿으로서 동작
- 인스턴스 생성은 필수, 인스턴스 초기화는 옵션
- new 연산자와 함께 생성자 함수 호출시 일어나는 과정
- 인스턴스 생성과 this 바인딩
- 암묵적으로 생성된 빈 객체는 this에 바인딩됨 (런타임 전에)
- 인스턴스 초기화
- 개발자에 의해 생성자 함수에 작성된 코드가 차례로 실행되며 this에 바인딩되어 있는 인스턴스 초기화 시킴
- 인스턴스 반환
- 함수 내부에서 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this를 반환함
- this가 아닌 다른 객체를 명시적으로 반환시 return 문에 명시한 객체가 반환됨
- 원시 값 반환시, 무시되고 this가 반환됨
- 명시적으로 this 외에 다른 값 반환은 반드시 생략해야 함
내부 메서드 [[Call]]과 [[Construct]]
- 함수 객체는 일반 객체가 가지고 있는 내부 슬롯과 내부 메서드 뿐만 아니라 함수로서 동작하기 위한 내부 슬롯과 메서드를 추가로 가지고 있음
- 함수가 일반 함수로서 호출되면 함수 객체의 내부 메서드 [[Call]]이 호출 → callable
- 함수가 생성자 함수로서 호출되면 내부 메서드 [[Construct]] 호출 → constructor
- 모든 함수 객체가 [[Construct]]를 갖는 것은 아님 ⇒ 함수 객체는 constructor일 수도 있고, non-constructor일 수도 있음
💡 모든 함수 객체는 호출할 수 있지만 (callable), 모든 함수 객체를 생성자 함수로서 호출할 수는 없다.
constructor와 non-constructor의 구분
⇒ 함수 정의 방식에 따라 구분함
- constructor : 함수 선언문, 함수 표현식, 클래스(클래스도 함수임)
- non-constructor : 메서드, 화살표 함수
- non-constructor인 함수 객체를 생성자 함수로서 호출하면 [[Construct]]가 없기 때문에 에러 발생
- 주의할 것은 생성자 함수로서 호출될 것을 기대하고 정의하지 않은 일반 함수에 new 연산자를 붙여 호출하면 생성자 함수처럼 동작할 수 있음
new 연산자
- new 연산자와 함께 호출하는 함수는 constructor이어야 함
- new 연산자 없이 생성자 함수를 호출하면 일반 함수로 호출됨
- 생성자 함수와 일반 함수를 구분하기 위해서 생성자 함수명을 Pascal case로 명명함
new.target
- new 연산자 없이 호출되는 것을 방지하기 위해서 함수 내에 new.target을 사용
- new.target을 사용하여 new 연산자와 함께 생성자 함수로서 호출되었는지 확인함
- new 연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리킴
- 일반 함수로서 호출된 함수 내부의 new.target은 undefined
Object와 Function 생성자 함수는 new 연산자 없이 호출해도 있을 때와 동일하게 동작
String, Number, Boolean 생성자 함수는 new 연산자 없이 호출시 각 문자열, 숫자, 불리언 값을 반환함