Skip to main content

17장 생성자 함수에 의한 객체 생성

17.1 Object 생성자 함수


new 연산자와 함께 Object 생성자 함수 호출한다.

생성자 함수 constructor 란 new 연산자와 함께 호출하여 객체 (인스턴스)를 생성하는 함수를 말한다. String, Number, Boolean, Function, Array, Date, RegExp, Promise 등 빌트인 생성자 함수가 있다.

const person = new Object();

17.2 생성자 함수

객체 리터럴에 의한 객체 생성 방식의 문제점

객체 리터럴에 의한 생성은 단 하나의 객체만 생성하기때문에 여러 개를 생성해야 하는 경우 같은 생성을 반복해야한다.

생성자 함수에 의한 객체 생성 방식의 장점

객체를 생성하기위한 템플릿(클래스)처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러개를 간편하게 생성할 수 있다.

다른 클래스 기반 객체지향 언어의 생성자와는 다르게 자바스크립트에서는 형식이 정해져 있는것이 아니고 일반 함수와 동일한 방법으로 생성자 함수를 정의하고 new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.

생성자 함수의 인스턴스 생성 과정

생성자 함수의 역할:

  • 인스턴스 생성 (필수)
  • 생성된 인스턴스를 초기화 (인스턴스 프로퍼티 추가 및 초기값 할당)
  • 생성자 함수에 반환하는 코드가 없어도 new 연산자와 함께 호출하면 엔진이 암묵적인 처리를 통해 인스턴스를 생성하고 반환한다.
  1. 인스턴스 생성과 this 바인딩

암묵적으로 빈 객체(인스턴스) 생성 → 인스턴스는 this 에 바인딩 (런타임 이전 실행) this 바인딩이란? this와 this 가 가리킬 객체를 연결

  1. 인스턴스 초기화

생성자 함수에 기술되어 있는 코드가 한줄씩 실행되어 인스턴스를 초기화 - 프로퍼티나 메서드를 추가하고, 인수로 전달받은 초기값을 할당하여 초기화하거나 고정값을 할당.

  1. 인스턴스 반환 함수 내부의 모든 처리가 끝난 후 인스턴스가 바인딩된 this 가 암묵적으로 반환된다.

명시적으로 객체를 반환하면 암묵적 this 반환은 무시되고, 객체가 반환된다. 하지만 명시적으로 원시 값을 반환하면 원시 값은 무시되고 암묵적으로 this가 반환된다. this가 아닌 값을 반환하는 것은 생성자 함수의 기본 동작을 훼손하므로 return 문을 반드시 생략해야한다.

function Circle(radius) {
//1. 암묵적으로 빈 객체 생성, this에 바인딩

//2. this에 바인딩되어 있는 인스턴스를 초기화
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
//3. 암묵적으로 this 반환
}

내부 메서드 [[Call]]과 [[Construct]]

함수 선언문, 함수 표현식으로 정의한 함수는 일반적인 함수, 생성자 함수 둘다로서 호출이 가능하다. 생성사 함수로 호출한다는건 new 연산자와 함께 호출해서 객체를 생성한다는 것이다.

함수 객체도 일반 객체가 갖고 있는 내부 슬롯과 내부 메서드를 모두 가지고 있기 때문에 일반 객체와 동일하게 동작할 수 있다. 다른 점은, 일반 객체는 호출할 수 없다.

함수는 일반 객체의 내부 슬롯, 내부 메서드에 추가로 environment, FormalParameters 등의 내부 슬롯과 call, construct 같은 내부 메서드를 가지고있다.

  • 일반 함수 호출 -> [[call]] 호출
  • 생성 자 함수 호출 ->[[contstruct]] 호출

함수 객체는 반드시 callable (내부 메서드 call을 갖고있음) 하지만 ontstructor 일수도, non-constructor 일수도 있다.

constructor & non-constructor

자바스크립트 엔진이 함수 정의를 평가하여 함수 객체를 생성할때 구분한다.

  • constructor: 함수 선언문, 함수 표현식, 클래스 (클래스도 함수)
  • non-constructor : 메서드(es6 메서드 축약표현), 화살표 함수

*ECMAScript 사양에서 메서드로 인정하는 범위가 일반적인 의미의 메서드보다 좁다는 것 주의 (es6의 메서드 축약 표현만 의미)

const baz = {
x: function () {},
};
new baz.x(); // x {}

//메서드 정의: Es6의 메서드 축약 표현만 메서드로 인정
const obj = {
x() {},
};

new obj.x(); // TypeError: obj.x is not a constructor

함수가 어디에 할당되어 있는지에 따라 메서드인지 판단하는게 아니라 함수 정의 방식에 따라 constructor, non-constructor를 구분한다.

함수 선언문과 함수 표현식으로 정의된 함수만이 constructor 이고 화살표 함수, 메서드 축약 표현으로 정의된 함수는 non-constructor 이다.

new 연산자

new 연산자와 함께 생성자 함수로서 호출하며 함수 내부의 this는 함수가 생성할 인스턴스를 가리킨다. 하지만 일반 함수로 호출하면 this는 전역 객체 window를 가리킨다.

new.target

es6 에서 지원. this와 유사하게 constructor 인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용되고 메타 프로퍼티라고 부른다.

new 연산자와 함께 생성자 함수로서 호출되면 함수내부의 new.target은 함수 자신을 가리킨다. 일반 함수로서 호출되면 new.target은 undefined이다.

따라서 new.target을 이용하여 함수가 어떻게 호출되었는지 확인할 수 있다.

참고: 빌트인 생성자 함수중 Object, Function은 new 연산자 없이 호출해도 함께 호출했을때와 동일하게 동작한다. String, Number, Boolean은 new 연산자가있으면 객체를 생성 반환, 없으면 변환된 값을 반환한다.