모던자바스크립트 Deep Dive

[17장] 생성자 함수에 의한 객체 생성 - 2

Ama_grammer 2024. 8. 28. 16:54

- 목표

  1. 생성자 함수의 인스턴스 생성과정을 알아보자.
  2. 내부 메서드 [[Call]] 과 [[Construct]]를 알아보고 비교해보자.
  3. constructor와 non-constructor를 구분해보자.

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

생성자 함수의 역할은 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿(클래스)으로서 동작하여 인스턴스를 생성하는 것과 생성된 인스턴스를 초기화(인스턴스 프로퍼티 추가 및 초기값 할당)하는 것이다.

 

인스턴스 생성 과정

  1. 인스턴스 생성과 this 바인딩
  2. 인스턴스 초기화
  3. 인스턴스 반환

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

암묵적으로 빈 객체가 생성된다. 이 객체는 완성된 객체는 아니나 생성자 함수가 생성한 인스턴스로 분류된다.

그리고 이 객체는 this에 바인딩 된다.

바인딩식별자와 값을 연결하는 과정이다.
function Output(text){
    // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
    console.log(this); // Ouput {}
 
    this.text = text;
    this.getTextLength = function() {
      return this.text.length;
    }
}

 

2. 인스턴스 초기화

생성자 함수에 기술되어 있는 코드가 한 줄씩 실행되어 this에 바인딩되어 있는 인스턴스를 초기화한다.

function Output(text){
    // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.

    console.log(this); // Ouput {}
    // 2. this에 바인딩되어 있는 인스턴스를 초기화한다.
    this.text = text;
    this.getTextLength = function() {
        return this.text.length;
    }
}

3. 인스턴스 반환

생성자 함수 내부에서 모든 처리가 끝났을 경우 완성된 인스턴스가 바인딩된 this를 암묵적으로 반환한다.

function Output(text){
    // 1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.

    console.log(this); // Ouput {}
    // 2. this에 바인딩되어 있는 인스턴스를 초기화한다.
    this.text = text;
    this.getTextLength = function() {
        return this.text.length;
    }
    // 3. 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
}

// 인스턴스 생성. Output 생성자 함수는 암묵적으로 this를 반환한다.
const output = new Output('hello world!!!');
console.log(output); // Output {text:'hello world!!!', getTextLength: f}

 

만약 this가 아닌 다른 객체를 명시적으로 반환하면 this가 반환되지 못하고 return문에 명시한 객체가 반환된다.

하지만, 명시적으로 원시 값을 반환하면 원시 값 반환은 무시되고 암묵적으로 this가 반환된다.

그렇기에 생성자 함수 내부에서 명시적으로 this 외 다른 값을 반환하는 것은 생성자 함수의 기본 동작을 훼손하기 때문에 

생성자 함수 내부에서는 return 문을 반드시 생략해야 한다.


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

Call : 함수가 일반 함수로서 호출됐을 때 호출되는 메서드

Construct : 함수가 생성자 함수(new연산자와 함께)로서 호출됐을 때 호출되는 메서드

 

function test() {}

// 일반적인 함수로서 호출: [[Call]]이 호출됨
test();

// 생성자 함수로서 호출: [[Construct]]가 호출됨
new test();

 

내부 메서드 [[Call]]을 갖는 함수 객체를 callable(호출할 수 있는 객체 : 함수)이라 하며

내부 메서드 [[Construct]]를 갖는 함수 객체constructor(생성자 함수로서 호출할 수 있는 함수),

내부 메서드 [[Construct]]를 갖지 않는 함수 객체non-constructor(객체를 생성자 함수로서 호출할 수 없는 함수)라고 부른다.


- constructor와 non-constructor 구분

자바스크립트 엔진은 함수 정의를 평가해 함수 객체를 생성할시 함수의 정의 방식에 따라 생성자형과 비 생성자형을 구분한다.

 

constructor : 함수 선언문, 함수 표현식, 클래스

//함수 선언문
function test() {
    console.log('프로그래밍 시험');
}

//함수 표현식
const test = function() {
    console.log('프로그래밍 시험');
}

//class
class Person {
    constructor(firstName, lastName, age) {
        this.firstName = firstName; 
        this.lastName = lastName;   
        this.age = age;             
    }
    getFullName() {
        return `${this.firstName} ${this.lastName}`;
    }

    getAge() {
        return `${this.firstName} is ${this.age} years old.`;
    }
}

 

non-constructor : 메서드(ES6 메서드 축약 표현), 화살표 함수

// 메서드 정의
const obj = {
    test() {
        console.log('프로그래밍 시험');
    }
}

//화살표 함수 정의(Arrow function)
const test = () => {
    console.log('프로그래밍 시험'):
}

 

  일반 함수로만 호출 가능한 객체 일반 함수 or 생성자 함수로 호출 가능한 객체
callable YES YES
non-constructor YES NO
constructor NO YES

 

❗️주의할점

생성자 함수로 호출될 것이라 기대하고 정의하지 않은 일반함수(callable && constructor)에 new 연산자를 붙여 호출하면 생성자 함수처럼 동작할 수 있다.


🔥 배운점

일반적인 함수와 생성자 함수의 차이가 내부 메서드에서도 각각 [[Call]], [[Construct]] 로 차이가 있음을 알았고,

모든 함수는 calllable 속성을 공유하나, 생성자인지 아닌지 여부에 따라 constructor와 non-constructor 속성으로 나뉘는 것을 알았다.

그리고, new 연산자를 일반함수에 붙이면 생성자 함수가 아님에도 생성자 함수처럼 동작 할수 있음에 주의해야겠다.

 

- 참고

https://developer.mozilla.org/ko/docs/Glossary/Constructor

'모던자바스크립트 Deep Dive' 카테고리의 다른 글

[42장] 비동기 프로그래밍 (1)  (1) 2025.02.14
[37장] Set 과 Map  (1) 2025.01.24
[35장] 스프레드 문  (0) 2025.01.16
[22장] this  (3) 2024.09.10
[17장] 생성자 함수에 의한 객체 생성 - 1  (2) 2024.08.20