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

heejung·2022년 3월 31일
0

deep dive

목록 보기
15/20

생성자 함수란 new 연산자와 함께 호출하여 객체를 생성하는 함수를 말한다. 생성자 함수에 의해 생성된 객체를 인스턴스라고 한다.

자바스크립트는 Object 생성자 함수 이외에도 String, Number, Boolean, Function, Array, Date, RegExp, Promise 등의 빌트인 생성자 함수를 제공한다.

Object 생성자 함수

  • new Object()
  • 빈 객체를 생성하여 반환


생성자 함수

객체 리터럴에 의한 객체 생성

  • 직관적이고 간편함
  • 단 하나의 객체만 생성 => 동일한 프로퍼티의 객체 여러개 생성해야할 때 비효율적

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

  • 프로퍼티 구조가 동일한 객체 여러개를 간편하게 생성
  • 일반 함수와 동일하게 정의하고 new 연산자와 함께 호출

인스턴스 생성 과정

  1. 인스턴스 생성과 this 바인딩

    암묵적으로 빈 객체가 생성되고, 이 객체가 this에 바인딩된다. 따라서 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
    이 처리는 런타임 이전에 실행된다.

  2. 인스턴스 초기화

    this에 바인딩되어 있는 인스턴스에 프로퍼티나 메소드를 추가하고, 인수로 전달받은 초기값을 인스턴스 프로퍼티에 할당한다.

  3. 인스턴스 반환

    완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
    만약 this가 아닌 다른 객체를 명시적으로 반환하면 this 반환은 무시되고 return 문에 명시한 객체가 반환된다.

function Circle(radius) {
  // 1. 인스턴스 생성과 this 바인딩
  
  // 2. 인스턴스 초기화
  this.radius = radius;
  this.getDiameter = function() {
    return 2 * this.radius;
  };
  
  // 3. 인스턴스 반환 => 암묵적으로 this 반환
  return {}; // 다른 객체를 명시적으로 반환 => this 반환 무시
}

그러나, 명시적으로 원시값을 반환하면 원시값 반환이 무시되고 암묵적으로 this가 반환된다.

생성자 함수 내부에서 명시적으로 this가 아닌 다른 값을 반환하는 것은 생성자 함수의 기본 동작을 훼손한다. 따라서 생성자 함수 내부에서 return 문을 반드시 생략해야 한다.

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

  • 함수도 객체이므로 일반 객체가 가지고 있는 내부 슬롯, 내부 메소드를 가지고 있음
  • 함수 객체만을 위한 [[Environment]], [[FormalParameters]] 등의 내부 슬롯과 [[Call]], [[Construct]] 등의 내부 메소드를 추가로 가짐
  • [[Call]] => 일반 함수로 호출
  • [[Construct]] => 생성자 함수로 호출

모든 함수는 호출이 가능해야하므로 [[Call]] 을 가지고 있지만, [[Construct]] 는 생성자 함수여야만 가진다.

constructor 와 non-constructor 의 구분

  • 자바스크립트 엔진이 함수 객체 생성 시 함수 정의 방식에 따라 구분
  • constructor : 함수 선언문, 함수 표현식, 클래스
  • non-constructor : 메소드(ES6 메소드 축약 표현), 화살표 함수
// 아래와 같이 일반 함수로 정의된 함수만이 constructor

// 함수 선언문
function foo() {}
// 함수 표현식
const bar = function() {};
const baz = {
  x: function() {} // x 값으로 할당된 것은 일반 함수로 정의된 함수 => 메소드 X
};
// non-constructor

// 화살표 함수
const arrow = () => {};
const obj = {
  x() {} // ES6 메소드 축약 표현
};

new.target

  • 생성자 함수가 new 연산자 없이 호출되는 것을 방지
  • constructor 함수 내부에서 암묵적인 지역 변수와 같이 사용됨
  • 함수 내부에서 사용 => new 연산자와 생성자 함수로서 호출했는지 확인
// 생성자 함수
function Circle(radius) {
  // new와 함께 호출하지 않았다면 new.target 은 undefined
  if (!new.target) {
    // new 연산자와 함께 생성자 함수 재귀 호출하여 반환
    return new Circle(radius);
  }
  
  this.radius = radius;
  this.getDiameter = function() {
    return 2 * this.radius;
  };
}

대부분의 빌트인 생성자 함수는 new 연산자와 함께 호출되었는지 확인한 후 적절한 값을 반환한다. new 연산자 없이 호출해도 new 연산자와 함께 호출했을 때와 동일하게 동작하는 것이다.

하지만 String, Number, Boolean 생성자 함수는 new 연산자 없이 호출하면 객체가 아닌 문자열, 숫자, 불리언 값을 반환한다. 이를 통해 데이터 타입을 변환하기도 한다.

const str = String(123);
console.log(str, typeof str); // 123 string

const num = Number('123');
console.log(num, typeof num); // 123 number

const bool = Boolean('true');
console.log(bool, typeof bool); // true boolean
profile
프론트엔드 공부 기록

0개의 댓글