[모던자바스크립트 딥다이브] 17장 생성자 함수에 의한 객체 생성

2023. 8. 16. 23:26스터디/모던자바스크립트딥다이브

Review

  • 자바스크립트 객체 생성 방식
    1. 객체 리터럴
    2. Object 생성자 함수
    3. 생성자 함수
    4. Object.create 메섣,
    5. 클래스(ES6)

Object 생성자 함수

  • new 연산자와 함께 Object 생성자 함수를 호출 → 빈 객체를 생성하여 반환
  • 반환된 빈 객체에 프로퍼티 또는 메서드를 추가하여 객체를 완성할 수 있다.
// 빈 객체 생성
const resume = new Object()

// 프로퍼티 추가
resume.name = '김말순'
resume.career = 2.3
resume.submit = function(){
    console.log('안녕하십니까. 지원자 김말순 입니다.')
}

생성자 함수

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

  • 객체 리터럴에 의한 객체 생성 방식
  • 장점 : 직관적, 편리
  • 단점 : 단 하나의 객체만 생성하므로 동일한 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우 비효율적

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

  • 객체를 생성하기 위한 템플릿 처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체를 여러개 생성할 수 있다. ( 클래스와 비슷, 붕어빵틀 )
function Bread(cost){
    // 생성자 함수의 this는 생성자 함수가 미래에 생성할 객체 인스턴스를 가르킨다.
    this.cost = cost;
    this.getPrice = fucntion(){
        return 3*this.cost
    }
}
const baguette = new Bread(5)
const croissant = new Bread(10)

console.log(baguette.getPrice(), croissant.getPrice())

// new 연산자가 없으면 일반 함수로 호출된다.
const waffle = Bread(2)
// 따라서 내부 this 는 전역을 가르키고, 리턴문이 없어 결과를 반환하지 않는다.
console.log(waffle) //undefiend

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

  • 생성자 함수의 역할 : 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿이므로 인스턴스를 생성하고, 인스턴스의 값을 할당한다
  • new 연산자를 사용해서 생성자 함수를 시행하면 자바스크립트 엔진은 암묵적으로 인스턴스를 생성하고 반환한다.
    1. 인스턴스 생성 this 바인딩 - 빈 객체를 생성하고 this에 바인딩 한다.
    2. 인스턴스 초기화 - 생성자 함수에 코드를 한줄씩 실행하며 초기화 한다.
    3. 인스턴스 반환 - 암묵적으로 인스턴스가 바인딩된 this가 반환된다. 만약 명시적으로 return 문을 통해 다른 객체를 반환하면 this가 반환되지 못하고 return 문에 해당하는 객체가 반환된다. → 기본 동작을 훼손하므로 생성자 함수에서는 return 문을 생략해야 한다

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

  • 함수가 일반 함수로 호출되면 함수 객체의 내부 메서드 [[Call]] 이 호출되고
  • 함수가 new 연산자와 함께 생성자 함수로서 호출되면 [[Construct]] 메서드가 호출되어 동작된다.
  • [[Call]] 내부 메서드를 가지는 함수 →callable (모든 함수 객체는 호출이 가능하므로 callable 에 해당한다.)
  • [[Construct]] 내부 메서드를 가지는 함수 →constructor
  • [[Construct]] 내부 메서드를 가지지 않는 함수 → non-constructor (즉, 함수지만 new 연산자와 함께 생성자 함수로 호출되지 못하고 일반 함수로만 호출되는 함수 객체)

5. constructor 와 non-constructor의 구분

자바스크립트 엔진의 구분 기준

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

non-constructor 로 판단하는 메서드는 일반적인 메서드(동작을 정의)보다 의미가 좁다. 메서드 축약 표현을 사용하여야만 메서드로 인식한다.

6. new 연산자

  • 일반 함수와 생성자 함수의 형식적 차이는 없다.
  • new 연산자와 함께 호출되는 함수면 생성자 함수
  • 따라서 생성자 함수는 파스칼 케이스 컨벤션을 사용해서 일반 함수와 구분

7. new.target

  • 파스칼 케이스 컨벤션을 사용해도 생성자 함수를 일반함수로 잘못 호출하는 경우를 방지하기 위해 ES6에 추가된 내용
  • new,.target은 해당 함수가 생성자 함수로 호출되었다면 true를 아니라면 false를 반환한다. 따라서 생성자 함수 내부에서 if문을 통해 new.target의 값을 확인하여 만약 생성자 함수인데 일반함수로 호출되었다면 재귀적으로 생성자 함수로 다시 호출할 수 있도록 하자. → ES6에서 지원하므로, new.target을 사용할 수 없는 상황이라면 스코프 세이프 생성자 패턴을 사용한다.