
유명한 샌드위치 가게에 가서 샌드위치를 하나 주문했다고 가정하자. 주문 내역을 객체로 만들어보면 다음과 같다.
const sandwich ={
name : '에그마요',
bread : '허니오트',
cheese : '아메리칸',
sauce : '스위트 어니언'
}
이렇게 주문 내역을 객체 리터럴로 선언할 수 있다. 2개를 주문하면? 아래와 같이 각각 선언해줄 수 있다.
const sandwich1 ={
name : '에그마요',
bread : '허니오트',
cheese : '아메리칸',
sauce : '스위트 어니언'
}
const sandwich2 ={
name : '햄',
bread : '위트',
cheese : '슈레드',
sauce : '사우스 웨스트'
}
그런데 만약 샌드위치를 100개를 주문한다면 어떨까? 객체 리터럴로 하나씩 만든다면 100개의 각각 다른 샌드위치 객체를 선언해야한다. 이는 너무 번거롭다. 어차피 프로퍼티가 동일한데 좀 더 쉽게 객체를 만들어낼 수 없을까?
이때 사용할 수 있는 것이 생성자 함수(Constructor)이다. 앞에서 주문했던 2가지 샌드위치를 생성자 함수를 이용하여 선언하면 다음과 같다.
function Sandwich(name, bread, cheese, sauce){
this.name = name;
this.bread = bread;
this.cheese = cheese;
this.sauce = sauce;
this.sayMenu = function(){
console.log(`주문하신 ${this.name} 샌드위치 나왔습니다!`)
}
}
const order1 = new Sandwich('에그마요', '허니오트', '아메리칸', '스위트 어니언');
const order2 = new Sandwich('햄', '위트', '슈레드', '사우스 웨스트');
생성자 함수는 마치 템플릿과 같다. 동일한 프로퍼티 구조의 객체를 만들고 싶다면 생성자 함수라는 템플릿을 만들어 놓으면 된다. 그리고 new 연산자와 함께 호출하여 객체를 생성한다. 이때 생성된 객체를 인스턴스(Instance)라고 한다. 생성자 함수 안에서의 this는 생성되는 객체, 즉 인스턴스를 가리킨다.

위의 order1과 order2를 콘솔에서 찍어보면 위와 같이 객체가 생성된 것을 확인할 수 있다. 생성자 함수에는 함수 즉,메서드를 정의할 수도 있다.
- 빈 객체(인스턴스)가 생성된다.
- 인스턴스는 this에 바인딩된다.
- this에 바인딩되어 있는 인스턴스에 프로퍼티나 메서드를 추가하고, 초기값을 인스턴스 프로터티에 할당하여 초기화한다.
- 모든 처리가 끝나면 인스턴스가 바인딩된 this를 반환한다.
생성자 함수 내부에 직접 함수(메서드)를 정의하는 방식은 메모리 효율성 측면에서 단점이 있다. 생성자 함수 내부에 메서드를 정의하면 생성자 함수로부터 생성된 인스턴스마다 함수가 계속해서 새로 생성된다. 생성한 인스턴스가 많다면 메모리 사용량이 더 늘어나게 된다.
또한, 유지보수 측면에서도 비효율적일 수 있다. 생성자 함수 내부에서 메서드를 정의한 경우에, 해당 함수를 변경하려면 모든 객체마다 따로 수정해야한다.
이를 좀 더 효율적으로 사용할 수 있도록 하는 것이 바로 프로토타입(Prototype)이다. 이는 다음 포스팅에서 좀 더 자세히 다루어보도록 하겠다.