본문 바로가기
개념 정리/모던 자바스크립트 딥다이브

모던 자바스크립트 : 생성자 함수에 의한 객체 생성

by 매진2 2023. 11. 7.
728x90

생성자 함수로 객체 생성하는 방법에 대해 알아보자

  • 객체 리터럴에 의한 객체 생성 방식은 가장 일반적이고 간단한 객체 생성 방식
  • 생성자 함수와 일반함수 형식적 차이가 없기 때문에 첫 문자를 대문자로 기술하여 구별

1. Object 생성자 함수

a. 생성자 함수로 객체 생성 과정

  • new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체 생성해 반환
  • 빈 객체 생성 후 프로퍼티 또는 메서드 추가해 객체 완성

b. 생성자 함수란?

  • 생성자 함수 : new 연산자와 함께 호출하여 객체(인스턴스) 생성하는 함수
  • 인스턴스 : 생성자 함수에 의해 생성된 객체
  • Object 생성자 함수 외에도 String, Number, Boolean, Function, Array, Date, RegExp, Promise 등 빌트인 생성자 함수 제공

c. 그러면 무조건 생성자 함수를 쓰는게 좋나?

  • 반드시 Object 생성자 함수를 사용해 빈객체 생성해야하는 것은 아님 => 특별한 이유가 있을때만 사용
  • 객체 생성 방법은 객체 리터럴 사용하는것이 더 간편

 

2. 생성자 함수

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

  • 객체 리터럴에 의한 객체 생성 방식은 단 하나의 객체만 생성
    • 동일한 프로퍼티 갖는 객체를 여러개 생성해야하는 경우 매번 같은 프로퍼티 기술해야해서 비효율적
  • 프로퍼티 구조가 동일하더라도 매번 같은 프로퍼티와 메서드 기술해야함
    • 객체는 프로퍼티 통해 객체 고유 상태 표현
    • 메서드 통해 상태 데이터인 프로퍼티를 참조하고 조작하는 동작 표현
    • 프로퍼티는 객체마다 프로퍼티 값이 다를 수 있지만 메서드는 내용이 동일한 경우가 일반적

 

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

  • 생성자 함수를 사용해 프로퍼티 구조가 동일한 객체 여러개 간편 생성 가능
  • 생성자 함수 : 객체(인스턴스) 생성하는 함수
  • 일반 함수와 동일한 방법으로 생성자 함수 정의하고 new 연산자와 함께 호출하면 해당함수는 생성자 함수로 동작

 

**this

  • this : 객체 자신의 프로퍼티나 메서드 참조하기 위한 자기 참조 변수
  • this가 가리키는 값 = this 바인딩 = 호출 방식에 따라 동적 결정

전역 객체는 브라우저에서는 window, Node.js에서는 global rkflzla

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

생성자 함수의 역할

  1. 필수 : 프로퍼티 구조가 동일한 인스턴스 생성하기 위한 템플릿(클래스)로 동작해 인스턴스 생성
  2. 옵션 : 생성된 인스턴스 초기화(인스턴스 프로퍼티 추가 및 초기값 할당)

new 연산자로 생성자 함수 호출하면

  • 자바스크립트 엔진은 암묵적인 처리를 통해 인스턴스 생성하고
  • 인스턴스 초기화 후
  • 암묵적으로 인스턴스 반환

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

  • 암묵적으로 빈 객체 생성 => 빈 객체가 생성자 함수가 생성한 인스턴스가 될 예정
  • 빈객체는 this에 바인딩 => 생성자 함수 내부의 this가 생성자 함수가 생성할 인스턴스를 가리킴
  • 이 처리는 런타임 이전에 실행
  • 바인딩 : 식별자와 값을 연결하는 과정

c-2. 인스턴스 초기화

  • 생성자 함수에 기술되어 있는 코드가 한줄씩 실행되어 this 바인딩 되어있는 인스턴스 초기화
  • this에 바인딩 되어있는 인스턴스에 프로퍼티나 메서드 추가
  • 생성자 함수가 인수로 전달받은 초기값을 인스턴스 프로퍼티에 할당해 초기화 하거나 고정값 할당
  • 이 처리는 개발자가 기술 

c-3. 인스턴스 반환

  1. 생성자 함수 내부에서 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this 암묵적 반환
  2. 만약 this가 아닌 다른 객체를 명시적으로 반환하면 this가 반환되지 못하고 return 문에 명시한 객체 반환
  3. 명시적으로 원시값을 반환하면 원시값 반환 무시되고 암묵적으로 this 반환

=> 생성자 함수 내부에서 명시적으로 this가 아닌 다른 값을 반환하는 것은 생성자 함수의 기본 동작 훼손

=> 생성자 함수 내부에서 return 문 반드시 생략

 

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

d-1. 함수는 객체이므로 일반 객체와 동일하게 동작 가능

  • 함수 선언문 또는 함수 표현식으로 정의한 함수는 일반적인 함수로서 호출할 수 있는 것은 물론 생성자 함수로도 호출 가능
  • new 연산자와 함께 호출해 객체 생성 가능
  • 함수 객체는 일반 객체가 가진 내부 슬롯과 내부 메서드 모두 가지고 있음
  • [[Environment]], [[FornalParameters]], [[Call]], [[Construct]] 추가 보유

d-2. 함수는 호출 가능한 객체

  • 함수가 일반함수로 호출되면  [[Call]] 호출
  • new 연산자로 생성자 함수로 호출되면 [[Construct]] 호출

d-3. callable, constructor, none-constructor

  • callable : 내부 메서드 [[Call]]을 갖는 함수 객체, 함수 객체는 반드시 callable이어야함 => 모든 함수 객체가 보유
  • constructor : [[Construct]] 를 갖는 함수 객체, 생성자 함수로 호출가능, 모두 가지고 있는건 아님
  • none-constructor : [[Construct]] 를 갖지 않는 함수 객체, 생성자 함수로 호출할 수 없는 함수
  • 모든 함수 객체는 호출 가능하지만 무조건 생성자 함수로 호출 가능한 건 아님

e. constructor와 non-constructor의 구분

  • 자바스크립트 엔진은 함수 객체 생성할 때 함수 정의 방식에 따라 함수를 constructor와 non-constructor로 구분
    • constructor : 함수 선언문, 함수 표현식, 클래스
    • non-constructor : 메서드, 화살표 함수
      • ECMAScript 사양에서 메서드란 ES6의 메서드 축약 표현만 의미
  • 주의 : 생성자 함수로 사용하지 않을 일반함수를 new 연산자 붙여 호출하면 생성자 함수처럼 동작

f. new 연산자

f-1. 일반 함수를 new 연산자를 붙여 호출했을 때

f-2. 생성자 함수를 일반 함수처럼 호출했을 때

  • Circle 함수를 new 연산자와 함께 생성자 함수로서 호출하면 함수 내부의 this는 Circle 생성자 함수가 생성할 인스턴스 가리킴
  • 하지만 Circle 함수를 일반적인 함수로서 호출하면 함수 내부의 this는 전역 객체 window 가리킴
  • radius 프로퍼티와 getDiameter 메서드는 전역객체의 프로퍼티와 메서드가 됨

g. new.target

g-1. new.target

  • new.target은 this와 유사하게 constructir인 모든 함수 내부에서 암묵적인 지역 변수와 같이 사용
  • 메타 프로퍼티라고 부름
  • 생성자 함수가 new 연산자 없이 호출되는 것 방지 위해 ES6에서 new.target 지원 but IE는 지원 안함
  • 함수 내부에서 new.target 사용하면 new 연산자로 생성자 함수 호출되었는지 확인 가능
    • new 연산자 있다면 new.target은 함수 자신을 가리킴
    • new 연산자 없이 일반 함수로 호출된경우 new.target은 undefined
  • new 연산자와 함께 생성자 함수에 의해 생성된 객체(인스턴스)는 프로토 타입에 의해 생성자 함수와 연결
    • 이를 이용해 new 연산자로 호출되었는지 확인 가능

 

g-2. 스코프 세이브 생성자 패턴

  • new.target을 사용할 수 없는 상황에 스코프 세이브 생성자 패턴 사용

 

g-3. 예시

  • Object, Function
    • new 연산자 없이 호출해도 new 연산자와 함께 호출했을 때와 동일하게 동작
  • String, number, Boolean
    • new 연산자와 함께 호출 시 객체 생성해 반환
    • new 없이 호출 시 문자열, 숫자, 불리언 값 반환 => 이걸로 데이터 타입 변환 가능

 

 

 

 

모던 자바스크립트 딥다이브 책을 정리한 내용입니다!!!!
728x90